Kullanmak arasında bir tercih veya davranış farkı var mı:
if(obj.getClass().isArray()) {}
ve
if(obj instanceof Object[]) {}
?
Kullanmak arasında bir tercih veya davranış farkı var mı:
if(obj.getClass().isArray()) {}
ve
if(obj instanceof Object[]) {}
?
Yanıtlar:
Çoğu durumda, instanceof
bir nesnenin dizi olup olmadığını test etmek için operatörü kullanmalısınız .
Genellikle, bir nesnenin türünü derleme zamanında bilinen belirli bir türe indirmeden önce test edersiniz. Örneğin, belki bir Integer[]
veya bir ile çalışabilecek bir kod yazdınız int[]
. Oyuncularınızı aşağıdakilerle korumak istersiniz instanceof
:
if (obj instanceof Integer[]) {
Integer[] array = (Integer[]) obj;
/* Use the boxed array */
} else if (obj instanceof int[]) {
int[] array = (int[]) obj;
/* Use the primitive array */
} else ...
JVM seviyesinde, instanceof
operatör çoğu JVM uygulamasında optimize edilen belirli bir "örnek" bayt koduna çevirir .
Daha nadir durumlarda, bilinmeyen türlerde bir nesne grafiğini hareket ettirmek için yansıma kullanıyor olabilirsiniz. Bu gibi durumlarda isArray()
, derleme zamanında bileşen türünü bilmediğiniz için yöntem yararlı olabilir; örneğin, bir tür serileştirme mekanizması uyguluyor olabilir ve türden bağımsız olarak dizinin her bileşenini aynı serileştirme yöntemine geçirebilirsiniz.
İki özel durum vardır: boş referanslar ve ilkel dizilere referanslar.
Bir boş başvuru neden olur instanceof
sonuçlanması false
ise, isArray
bir atar NullPointerException
.
İlkel bir diziye instanceof
uygulandığında false
, sağ taraftaki bileşen türü bileşen türü ile tam olarak eşleşmediği sürece verim elde edilir . Aksine, herhangi bir bileşen türü için isArray()
dönecektir true
.
obj instanceof int[]
verimi false
bir atamak int[]
için obj
, yanılıyorsunuz.
obj instanceof Object[]
verimi false
ise Object obj = new int[7]
.
java.lang.Object
, bu nedenle mantıklıdır. Ancak instanceof
yine de ilkel dizileri test etmek için kullanılabilir.
isArray()
kullanılmalıdır. Çok genel olmayan bir durumda, sadece nesne dizilerine sahip olmak, instanceof
yüksek performanslı bir alternatif sunar.
Eğer obj
tür int[]
ise, o zaman bir dizi olacak, Class
ancak bir örneği olmayacaktır Object[]
. Peki ne yapmak istiyorsun obj
. Eğer yayınlayacaksan, git instanceof
. Yansımayı kullanacaksanız, kullanın .getClass().isArray()
.
getClass().isArray()
Sun Java 5 veya 6 JRE'de IBM'den önemli ölçüde daha yavaştır.
O kadar kullanarak bu clazz.getName().charAt(0) == '['
hızlı Sun JVM üzerindedir.
Geçenlerde Groovy uygulamasını JDK 5'ten JDK 6'ya yükseltme konusunda bir sorunla karşılaştım isArray()
. JDK6'da kullanım başarısız oldu:
MissingMethodException:
No signature of sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl.isArray() ...
instanceof Object[]
Bunu düzeltmek için değiştirme .
isArray
bir yöntemdir Class
, değil Type
, bu yüzden elbette GenericArrayTypeImpl
bu yöntem yoktur. Ve getClass
asla bir olmayan dönemezsiniz Class
Type
, bu yüzden (veya Groovy ??) bunu almak için yanlış bir şey yapmış olmalısınız, her Type
biri bir olduğunu varsayalım Class
.
Java dizisi yansıması, üzerinde "instanceof" yapmak için kullanılabilir Sınıf örneğinin bulunmadığı durumlar içindir. Örneğin, JPA gibi sınıfın yeni bir örneğine değerler enjekte eden bir tür enjeksiyon çerçevesi yazıyorsanız, isArray () işlevini kullanmanız gerekir.
Bu konuda Aralık ayının başlarında blog yazdım. http://blog.adamsbros.org/2010/12/08/java-array-reflection/
Yansıtıcı bir çözüm ile yansıtıcı olmayan bir çözüm arasında bir seçeneğiniz varsa, asla yansıtıcı olanı (Sınıf nesnelerini içeren) seçmeyin. Bu "Yanlış" ya da herhangi bir şey değil, ama yansımayı içeren her şey genellikle daha az açık ve daha az açıktır.
İkisi arasında bulabildiğim davranış farkı yok (bariz boş durum dışında). Hangi sürümü tercih edeceğim, ikinci ile giderdim. Bunu Java'da yapmanın standart yoludur.
Kodunuzun okuyucularını karıştırırsa ( String[] instanceof Object[]
doğru olduğu için), kod inceleyenleri sormaya devam ederse daha açık olmak için ilkini kullanmak isteyebilirsiniz.