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, instanceofbir 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, instanceofoperatö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ı falseise, isArraybir atar NullPointerException.
İlkel bir diziye instanceofuygulandığı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 falsebir atamak int[]için obj, yanılıyorsunuz.
obj instanceof Object[]verimi falseise Object obj = new int[7].
java.lang.Object, bu nedenle mantıklıdır. Ancak instanceofyine de ilkel dizileri test etmek için kullanılabilir.
isArray()kullanılmalıdır. Çok genel olmayan bir durumda, sadece nesne dizilerine sahip olmak, instanceofyüksek performanslı bir alternatif sunar.
Eğer objtür int[]ise, o zaman bir dizi olacak, Classancak 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 .
isArraybir yöntemdir Class, değil Type, bu yüzden elbette GenericArrayTypeImplbu yöntem yoktur. Ve getClassasla bir olmayan dönemezsiniz Class Type, bu yüzden (veya Groovy ??) bunu almak için yanlış bir şey yapmış olmalısınız, her Typebiri 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.