Saya memiliki Object[]
array, dan saya mencoba menemukan yang primitif. Saya sudah mencoba menggunakan Class.isPrimitive()
, tetapi sepertinya saya melakukan sesuatu yang salah:
int i = 3;
Object o = i;
System.out.println(o.getClass().getName() + ", " +
o.getClass().isPrimitive());
cetakan java.lang.Integer, false
.
Apakah ada cara yang benar atau alternatif?
java
reflection
drill3r
sumber
sumber
int.class.isPrimitive()
hasiltrue
;Integer.class.isPrimitive()
hasilfalse
.Jawaban:
Tipe dalam an
Object[]
tidak akan pernah benar - benar primitif - karena Anda punya referensi! Di sini jenisnyai
adalahint
sedangkan jenis objek yang dirujuko
adalahInteger
(karena auto-boxing).Sepertinya Anda perlu mencari tahu apakah jenisnya adalah "pembungkus untuk primitif". Saya tidak berpikir ada sesuatu yang dibangun ke dalam pustaka standar untuk ini, tetapi mudah untuk membuat kode:
sumber
java.lang.<type>.TYPE
setelah semua, yang tentu saja primitif itu sendiri. Sepertinya saya tidak akan dapat menghindari pemeriksaan untuk setiap jenis secara individual, terima kasih untuk solusi yang bagus.HashSet
memungkinkan akses di O (1) sedangkan deretanif
pernyataan atauswitch
pernyataan membutuhkan O (# pembungkus) dalam kasus terburuk. Dalam praktiknya, patut dipertanyakan jikaif
pernyataan untuk jumlah tetap 9 pembungkus mungkin tidak lebih cepat daripada akses berbasis hash.commons-lang
ClassUtils
memiliki metode yang relevan .Versi baru memiliki:
Versi lama memiliki
wrapperToPrimitive(clazz)
metode, yang akan mengembalikan korespondensi primitif .sumber
Perpustakaan Guava Google memiliki sebuah utilitas Primitif bahwa cek jika kelas adalah jenis pembungkus untuk primitif:
Primitives.isWrapperType(class)
.Class.isPrimitive () berfungsi untuk primitif
sumber
Bagi yang suka kode singkat.
sumber
void.class.isPrimitive()
kembali benarVoid
isnull
;) berguna untuk membuatCallable<Void>
yang merupakan Callable yang tidak mengembalikan apapun.Mulai Java 1.5 dan yang lebih baru, ada fitur baru bernama auto-boxing. Kompilator melakukan ini sendiri. Saat melihat peluang, ia mengubah tipe primitif menjadi kelas pembungkus yang sesuai.
Yang mungkin terjadi di sini adalah saat Anda menyatakan
Kompilator akan mengkompilasi pernyataan ini sebagai perkataan
Ini adalah tinju otomatis. Ini akan menjelaskan keluaran yang Anda terima. Halaman ini dari spesifikasi Java 1.5 menjelaskan auto-boxing lebih detail.
sumber
Integer.valueOf(int)
sendiri hanya mengembalikan nilai yang di-cache jika argumennya adalah "satu byte" (baca: antara -128, 127, keduanya inklusif). Kalau tidak, itu panggilannew Integer(int)
. Lihat: developer.classpath.org/doc/java/lang/… , hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/…Integer
tidak primitif,Class.isPrimitive()
tidak berbohong.sumber
Saya pikir ini terjadi karena tinju otomatis .
Anda dapat mengimplementasikan metode utilitas yang cocok dengan kelas tinju spesifik ini dan memberi tahu Anda jika kelas tertentu primitif.
sumber
.equals
ke==
. Kelas adalah lajang.Anda harus berurusan dengan auto-boxing java.
Anda mendapatkan kelas test.class dan tes javap -c memungkinkan Anda memeriksa bytecode yang dihasilkan. Seperti yang Anda lihat, compiler java ditambahkan untuk membuat Integer baru dari int Anda dan kemudian menyimpan Objek baru itu di o melalui astore_2Mari kita ambil kodenya
sumber
sumber
Agar Anda dapat melihat bahwa isPrimitive dapat mengembalikan true (karena Anda memiliki cukup jawaban yang menunjukkan mengapa salah):
Ini penting dalam refleksi ketika sebuah metode mengambil "int" daripada "Integer".
Kode ini berfungsi:
Kode ini gagal (tidak dapat menemukan metode):
sumber
Seperti yang telah dikatakan beberapa orang, ini karena autoboxing .
Anda bisa membuat metode utilitas untuk memeriksa apakah kelas objek adalah
Integer
,Double
, dll Tapi ada tidak ada cara untuk mengetahui apakah obyek diciptakan oleh autoboxing primitif ; setelah dikotakkan, itu tampak seperti sebuah objek yang dibuat secara eksplisit.Jadi, kecuali jika Anda tahu pasti bahwa array Anda tidak akan pernah berisi kelas pembungkus tanpa autoboxing, tidak ada solusi nyata.
sumber
Jenis pembungkus primitif tidak akan menanggapi nilai ini. Ini untuk representasi kelas primitif, meskipun selain refleksi saya tidak bisa memikirkan terlalu banyak kegunaannya begitu saja. Jadi misalnya
mencetak "salah", tapi
mencetak "benar"
sumber
Saya terlambat ke pertunjukan, tetapi jika Anda menguji lapangan, Anda dapat menggunakan
getGenericType
:Dokumen Oracle mencantumkan 8 tipe primitif.
sumber
Ini adalah cara paling sederhana yang dapat saya pikirkan. Kelas pembungkus hanya ada dalam
java.lang
paket. Dan selain dari kelas pembungkus, tidak ada kelas lain di dalam yangjava.lang
memiliki field bernamaTYPE
. Anda dapat menggunakannya untuk memeriksa apakah suatu kelas adalah kelas pembungkus atau tidak.sumber
Dapatkan informasi tentang BeanUtils dari Spring http://static.springsource.org/spring/docs/3.0.x/javadoc-api/
Mungkin variasi Apache (kacang umum) memiliki fungsi yang serupa.
sumber
Anda dapat menentukan apakah suatu objek adalah tipe pembungkus dengan pernyataan di bawah ini:
dan Anda juga bisa menentukan objek primitif dengan menggunakan metode isPrimitive ()
sumber
sumber
Untuk pengguna javapoet juga ada cara ini:
sumber