Jika saya memiliki kelas seperti ini:
public class Whatever
{
public void aMethod(int aParam);
}
apakah ada cara untuk mengetahui yang aMethod
menggunakan parameter bernama aParam
, yaitu tipe int
?
java
reflection
Geo
sumber
sumber
Jawaban:
Untuk meringkas:
method.getParameterTypes()
Demi menulis fungsionalitas pelengkapan otomatis untuk editor (seperti yang Anda nyatakan di salah satu komentar) ada beberapa opsi:
arg0
,arg1
,arg2
dllintParam
,stringParam
,objectTypeParam
, dllsumber
Di Java 8 Anda dapat melakukan hal berikut:
Jadi untuk kelas Anda,
Whatever
kami dapat melakukan tes manual:yang akan dicetak
[aParam]
jika Anda telah memberikan-parameters
argumen ke compiler Java 8 Anda.Untuk pengguna Maven:
Untuk informasi lebih lanjut lihat tautan berikut:
sumber
Perpustakaan Paranamer dibuat untuk mengatasi masalah yang sama ini.
Ia mencoba untuk menentukan nama metode dengan beberapa cara berbeda. Jika kelas dikompilasi dengan debugging, ia dapat mengekstrak informasi dengan membaca bytecode kelas.
Cara lain adalah dengan menginjeksi anggota statis pribadi ke dalam bytecode kelas setelah dikompilasi, tetapi sebelum ditempatkan di dalam toples. Kemudian menggunakan refleksi untuk mengekstrak informasi ini dari kelas pada saat runtime.
https://github.com/paul-hammant/paranamer
Saya mengalami masalah saat menggunakan perpustakaan ini, tetapi pada akhirnya saya berhasil membuatnya berfungsi. Saya berharap untuk melaporkan masalah ini ke pengelola.
sumber
ParameterNAmesNotFoundException
lihat kelas org.springframework.core.DefaultParameterNameDiscoverer
sumber
Iya.
Kode harus dikompilasi dengan compiler yang sesuai dengan Java 8 dengan opsi untuk menyimpan nama parameter formal yang diaktifkan ( opsi -parameters ).
Maka cuplikan kode ini akan berfungsi:
sumber
Anda dapat mengambil metode dengan refleksi dan mendeteksi tipe argumennya. Periksa http://java.sun.com/j2se/1.4.2/docs/api/java/lang/reflect/Method.html#getParameterTypes%28%29
Namun, Anda tidak dapat memberi tahu nama argumen yang digunakan.
sumber
Itu mungkin dan Spring MVC 3 melakukannya, tetapi saya tidak meluangkan waktu untuk melihat persis bagaimana caranya.
Diambil dari dokumentasi musim semi
sumber
Meskipun tidak mungkin (seperti yang digambarkan orang lain), Anda bisa menggunakan anotasi untuk membawa nama parameter, dan mendapatkannya melalui refleksi.
Bukan solusi terbersih, tetapi menyelesaikan pekerjaan. Beberapa layanan web sebenarnya melakukan ini untuk menyimpan nama parameter (yaitu: menyebarkan WS dengan glassfish).
sumber
Lihat java.beans.ConstructorProperties , ini adalah anotasi yang dirancang untuk melakukan hal ini.
sumber
Jadi, Anda harus bisa melakukan:
Tetapi Anda mungkin akan mendapatkan daftar seperti ini:
Saya yakin ini akan diperbaiki di Groovy 2.5+
Jadi saat ini jawabannya adalah:
Lihat juga:
Untuk setiap metode, maka sesuatu seperti:
sumber
aMethod
. Saya ingin mendapatkannya untuk semua metode di kelas.antlr
untuk mendapatkan nama parameter untuk ini?jika Anda menggunakan gerhana, lihat gambar di bawah ini untuk memungkinkan kompiler menyimpan informasi tentang parameter metode
sumber
Seperti yang dinyatakan @Bozho, dimungkinkan untuk melakukannya jika informasi debug disertakan selama kompilasi. Ada jawaban yang bagus di sini ...
Bagaimana cara mendapatkan nama parameter konstruktor objek (refleksi)? oleh @AdamPaynter
... menggunakan perpustakaan ASM. Saya mengumpulkan contoh yang menunjukkan bagaimana Anda dapat mencapai tujuan Anda.
Pertama-tama, mulailah dengan pom.xml dengan dependensi ini.
Kemudian, kelas ini harus melakukan apa yang Anda inginkan. Panggil saja metode statis
getParameterNames()
.Berikut adalah contoh dengan unit test.
Anda dapat menemukan contoh lengkapnya di GitHub
Peringatan
static
metode. Ini karena dalam hal ini jumlah argumen yang dikembalikan oleh ASM berbeda, tetapi itu adalah sesuatu yang dapat diperbaiki dengan mudah.sumber
Nama parameter hanya berguna untuk kompilator. Ketika kompilator membuat file kelas, nama parameter tidak disertakan - daftar argumen metode hanya terdiri dari jumlah dan jenis argumennya. Jadi tidak mungkin untuk mengambil nama parameter menggunakan refleksi (seperti yang ditandai dalam pertanyaan Anda) - tidak ada di mana pun.
Namun, jika penggunaan refleksi bukanlah persyaratan yang sulit, Anda dapat mengambil informasi ini langsung dari kode sumber (dengan asumsi Anda memilikinya).
sumber
Parameter names are only useful to the compiler.
Salah. Lihatlah perpustakaan Retrofit. Ini menggunakan Antarmuka dinamis untuk membuat permintaan REST API. Salah satu fiturnya adalah kemampuan untuk menentukan nama placeholder di jalur URL dan mengganti placeholder tersebut dengan nama parameter yang sesuai.Untuk menambahkan 2 sen saya; info parameter tersedia dalam file kelas "untuk debugging" saat Anda menggunakan javac -g untuk mengompilasi sumber. Dan itu tersedia untuk APT tetapi Anda memerlukan anotasi sehingga tidak berguna bagi Anda. (Seseorang mendiskusikan hal serupa 4-5 tahun yang lalu di sini: http://forums.java.net/jive/thread.jspa?messageID=13467&tstart=0 )
Secara keseluruhan singkatnya Anda tidak bisa mendapatkannya kecuali Anda mengerjakan file Sumber secara langsung (mirip dengan apa yang dilakukan APT pada waktu kompilasi).
sumber