Apakah ada sesuatu seperti instanceOf (Class <?> C) di Java?

88

Saya ingin memeriksa apakah suatu objek oadalah turunan dari kelas Catau subkelas dari C.

Misalnya, jika padalah kelas Pointsaya ingin x.instanceOf(Point.class)menjadi truedan juga x.instanceOf(Object.class)untuk menjadi true.

Saya ingin itu bekerja juga untuk tipe primitif berkotak. Misalnya, jika xadalah Integermaka x.instanceOf(Integer.class)seharusnya true.

Apa ada yang seperti itu? Jika tidak, bagaimana cara menerapkan metode seperti itu?

snakile
sumber
menangani kelas kotak agak berantakan
dfa

Jawaban:

174

Class.isInstance melakukan apa yang Anda inginkan.

if (Point.class.isInstance(someObj)){
    ...
}

Tentu saja, Anda tidak boleh menggunakannya jika Anda bisa menggunakannya instanceof, tetapi untuk skenario refleksi sering kali berguna.

gustafc
sumber
6
@ Malu itu mungkin lebih lambat, tetapi yang lebih buruk adalah lebih sulit untuk dipahami! Jika ada cara yang sangat sederhana untuk melakukan sesuatu - seperti if (a instanceof Point)- tetapi Anda melakukannya dengan cara yang lebih berbelit-belit, siapa pun yang membaca kode pasti akan berpikir "oh, pasti ada alasan untuk hal ini dilakukan dengan cara yang sulit", dan lalu buka dokumen untuk mengetahui Class.isInstanceperbedaannya dari instanceof. Anda membuang waktu rekan kerja Anda.
gustafc
21

Saya ingin memeriksa apakah sebuah objek o adalah turunan dari kelas c atau subkelas dari c. Misalnya, jika p adalah kelas Point saya ingin x.instanceOf (Point.class)

Um ... Apa? Apakah o, p dan x itu?

Saya ingin itu bekerja juga untuk tipe primitif. Misalnya, jika x adalah integer maka x.instanceOf (Integer.class) dan juga x.instanceOf (Object.class) harus benar.

Tidak. Seharusnya tidak dikompilasi. Primitif bukanlah objek, dan Anda tidak dapat memanggil metode padanya.

Bagaimanapun, ada tiga hal, salah satunya pasti dapat mencapai apa yang Anda inginkan (mereka agak berbeda di mana tepatnya diterapkan:

  • The instanceofOperator jika Anda tahu kelas pada waktu kompilasi.
  • Class.isInstance () jika Anda ingin memeriksa kelas objek terhadap kelas yang tidak dikenal pada waktu kompilasi.
  • Class.isAssignableFrom () jika Anda ingin memeriksa penugasan yang diberikan dua objek kelas.
Michael Borgwardt
sumber
9
x instanceof Integer
x instanceof Object

Anda hanya perlu menggunakan sintaks yang benar

untuk tipe primitif, Anda harus melakukannya dengan sangat berbeda. Karena Anda tidak dapat membuat metode untuk mereka, Anda memerlukan kelas yang menyimpan metode tersebut. Jadi, alih-alih "x.instanceOf (Integer.Class)", Anda harus memanggil "MyClassComparer.instanceOf (x, Integer.Class)" atau sesuatu seperti itu. Ini dapat dengan mudah diimplementasikan dengan metode overloading, tetapi saya gagal melihat kasus ketika fungsionalitas itu diinginkan sama sekali.

Erich Kitzmueller
sumber
4

Sebenarnya di Java ada operator boolean yang disebut instanceof yang dapat digunakan untuk menentukan apakah suatu objek adalah turunan kelas, turunan subkelas, atau turunan kelas yang mengimplementasikan antarmuka tertentu.

if(obj instanceof SomeClass) {
    // Do something
}

Tutorial Java memiliki contoh yang bagus untuk operator ini

victor hugo
sumber
1
Anda tidak dapat menggunakan instanceof dengan tipe primitif
dfa
4
Dia bingung tipe primitif dengan objek. Silakan baca ... "Misalnya, jika x adalah integer maka x.instanceOf (Integer.class) dan juga x.instanceOf (Object.class) harus benar." Malu jika Anda menolak semua jawaban
victor hugo
Mendukung (sp) saran menggunakan Tutorial Java. Ini adalah referensi yang bagus untuk mempelajari bahasa itu sendiri.
luis.espinal
0

Anda dapat melakukan:

if (foo instanceof classNameYouWantToCheck) 
fmsf
sumber
Anda tidak dapat menggunakan instanceof dengan tipe primitif
dfa
Kelas itu hanya untuk menunjukkan bahwa dia harus menulis nama kelas di sana. Saya akan memperbaikinya
fmsf
0

"Saya ingin itu bekerja juga untuk tipe primitif. Misalnya, jika x adalah integer maka x.instanceOf (Integer.class) dan juga x.instanceOf (Object.class) harus benar."

Mengapa? Tipe primitif dan tipe referensi benar-benar terpisah. Int primitif bukanlah subtipe dari Integer atau Object. Jenis nilai primitif selalu diketahui secara statis pada waktu kompilasi, jadi tidak ada gunanya menguji jenisnya. Tentu, Anda dapat mengemas nilai primitif dan kemudian menguji tipenya:

(Integer)5 instanceof Integer

Tapi apa gunanya?

newacct
sumber
-2

Saya pikir Anda bingung tentang instanceof untuk benda mentah dan yang umum

obj instanceof Class
obj instanceof Class<?> // this is the one you want
Paul Bors
sumber
2
Anda tidak dapat menggunakan obat generik di sisi kanan operator instanceof karena penghapusan jenis.
Matthias
2
Tidak, kamu yang bingung. Anda harus menggunakan tipe mentah setelahnya instanceof.
Dawood ibn Kareem