Saya melihat peningkatan kinerja saat menggunakan getClass()
dan ==
operator melebihi instanceOf
operator.
Object str = new Integer("2000");
long starttime = System.nanoTime();
if(str instanceof String) {
System.out.println("its string");
} else {
if (str instanceof Integer) {
System.out.println("its integer");
}
}
System.out.println((System.nanoTime()-starttime));
starttime = System.nanoTime();
if(str.getClass() == String.class) {
System.out.println("its string in equals");
} else {
if(str.getClass() == Integer.class) {
System.out.println("its integer");
}
}
System.out.println((System.nanoTime()-starttime));
Apakah ada pedoman, yang mana yang akan digunakan getClass()
atau instanceOf
?
Diberikan skenario: Saya tahu kelas yang tepat untuk dicocokkan, yaitu String
, Integer
(ini adalah kelas terakhir), dll.
Apakah menggunakan instanceOf
operator merupakan praktik yang buruk?
java
class
instanceof
gumpal
sumber
sumber
Jawaban:
Alasan mengapa kinerja
instanceof
dangetClass() == ...
berbeda adalah karena mereka melakukan hal yang berbeda.instanceof
menguji apakah referensi objek di sisi kiri (kiri) adalah turunan dari tipe di sisi kanan (kanan) atau beberapa subtipe .getClass() == ...
menguji apakah jenisnya identik.Jadi rekomendasinya adalah mengabaikan masalah kinerja dan menggunakan alternatif yang memberi Anda jawaban yang Anda butuhkan.
Belum tentu. Terlalu sering menggunakan salah satu
instanceOf
ataugetClass()
mungkin "bau desain". Jika Anda tidak berhati-hati, Anda akan mendapatkan desain di mana penambahan subclass baru menghasilkan sejumlah besar pengerjaan ulang kode. Dalam kebanyakan situasi, pendekatan yang disukai adalah menggunakan polimorfisme.Namun, ada kasus di mana ini BUKAN "bau desain". Misalnya,
equals(Object)
Anda perlu menguji tipe sebenarnya dari argumen tersebut, dan mengembalikanfalse
jika tidak cocok. Ini paling baik dilakukan dengan menggunakangetClass()
.Istilah-istilah seperti "praktik terbaik", "praktik buruk", "bau desain", "antipattern", dan seterusnya harus digunakan dengan hemat dan diperlakukan dengan curiga. Mereka mendorong pemikiran hitam-putih. Lebih baik membuat penilaian Anda dalam konteks, daripada hanya berdasarkan dogma; misalnya, sesuatu yang dikatakan seseorang adalah "praktik terbaik".
sumber
code smell
untuk menggunakan baik. Artinya, ini adalah konsekuensi dari kode desain yang buruk (non-polimorfik) yang membuat Anda menggunakan keduanya. dapatkah saya menyimpulkan penggunaan salah satunya dengan cara ini?instanceof
&getClass()
muncul karena desain kode yang buruk (non-polimorfik). Apakah saya benar?instanceof
(misalnya) adalah desain yang buruk. Ada situasi di mana ini mungkin merupakan solusi terbaik. Sama untukgetClass()
. Saya akan mengulangi bahwa saya mengatakan "penggunaan berlebihan" dan bukan "penggunaan" . Setiap kasus perlu dinilai berdasarkan manfaatnya ... bukan dengan secara membabi buta menerapkan beberapa aturan dogmatis yang tidak berdasar.Apakah Anda ingin mencocokkan kelas secara tepat , misalnya hanya mencocokkan
FileInputStream
daripada subkelas mana punFileInputStream
? Jika ya, gunakangetClass()
dan==
. Saya biasanya akan melakukan ini dalam sebuahequals
, sehingga sebuah instance dari X tidak dianggap sama dengan sebuah instance dari subclass X - jika tidak, Anda dapat mengalami masalah simetri yang rumit. Di sisi lain, itu biasanya lebih berguna untuk membandingkan bahwa dua objek memiliki kelas yang sama daripada satu kelas tertentu.Jika tidak, gunakan
instanceof
. Perhatikan bahwa dengangetClass()
Anda perlu memastikan bahwa Anda memiliki referensi non-null untuk memulai, atau Anda akan mendapatkan aNullPointerException
, sedangkaninstanceof
hanya akan kembalifalse
jika operan pertama adalah null.Secara pribadi menurut saya
instanceof
lebih idiomatis - tetapi menggunakan salah satu dari mereka secara ekstensif adalah bau desain dalam banyak kasus.sumber
Saya tahu sudah lama sejak ini ditanyakan, tetapi saya belajar alternatif kemarin
Kami tahu Anda bisa melakukan:
tetapi bagaimana jika Anda tidak tahu persis jenis kelas apa yang dibutuhkan? Anda tidak dapat secara umum melakukan:
karena memberikan kesalahan kompilasi.
Sebagai gantinya, berikut adalah alternatif - isAssignableFrom ()
Sebagai contoh:
sumber
isAssignableFrom
. Cara yang benar untuk menuliso instanceof String
dengan refleksi adalahString.getClass().isInstance(o)
. Javadoc bahkan mengatakan demikian: Metode ini adalah padanan dinamis dariinstanceof
operator bahasa Java .getClass () memiliki batasan bahwa objek hanya sama dengan objek lain dari kelas yang sama, jenis waktu proses yang sama, seperti yang diilustrasikan dalam output kode di bawah ini:
Keluaran:
SubClass memperluas ParentClass. subClassInstance adalah turunan dari ParentClass.
GetClass () yang berbeda mengembalikan hasil dengan subClassInstance dan parentClassInstance.
sumber