İnstanceof öğesini çağırmadan önce boş kontrol gerekli mi?


1354

Geri mi null instanceof SomeClassdönecek falseya da atacak NullPointerExceptionmı?


Aynı türden null olmayan nesnelerde başarılı olmak üzere tasarlanmış herhangi bir Karşılaştırma veya Eşittir veya benzer bir yöntem için 'en iyi uygulama' başlangıç ​​(veya çok erken) satırı olarak 'önemli' veya en azından çok yararlıdır ve sizi 'aptal davalara' karşı tek bir satırda korur. daha az kod = daha az hata.

13
Tartmak için "bu yararlı mı?" tartışma - Kendi Java kodumu hiç yazmadım (bu yüzden özelliklerin nerede olduğunu kolayca bilmiyorum ve bir test derlemek çok önemsiz olurdu), ancak şu anda Java'yı manuel olarak JavaScript'e dönüştürüyorum. Kodum bir boş başvuru başarısız oldu ve bu googling bana beklenen davranış olduğunu ve örtük bir boş denetim eksik olduğunu doğruladı kabul edilen yanıtı görmek sağlar. Benim durumumda çok faydalı.
Scott Mermelstein

Yanıtlar:


1838

Hayır, instanceof komutunu kullanmadan önce bir boş denetime gerek yoktur.

İfadesi x instanceof SomeClassise falseeğer xolduğunu null.

Java Dil Spesifikasyonu, bölüm 15.20.2, "Tür karşılaştırma operatörü instanceof" :

"Çalışma zamanında, sonucu instanceofoperatörü olan truedeğeri ise RelationalExpression değildirnull ve referans için gölgeleri olabilir ReferenceType bir yükseltmeden ClassCastException. Aksi takdirde sonucudur false."

Eğer işlenen boşsa sonuç yanlıştır.


377
Bu yanıt, geçerli davranışın garantili davranışla aynı olmaması try itnedeniyle daha doğrudur .
Luke

3
Bu soru Joshua Bloch'un nesne eşitliği konusundaki bölümü sırasında Effective Java- amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683
Kevin Meredith

17
Özellikle, Öğe 8'de, equals () yöntemlerinde bir instanceof operatörünün iki amaca hizmet ettiğini not eder - argümanın hem null olmayan hem de doğru tipte olduğunu doğrular. “... [S] o ayrı bir boş denetime ihtiyacınız yok."
Andy Thomas

2
@BenThurley - Java'nın instanceofoperatörü neredeyse 20 yıl önce piyasaya sürülen Java 1.0'ın bir parçasıydı. Davranışı şimdi mevcut kodu kıracak şekilde değiştirmek olası değildir, bu büyük maliyetten ağır basan bir fayda yoktur. Yirmi yıl önce, argümanın ortaya çıkabilmesi durumunda doğruyu döndürmek için argümanlar olabilirdi veya boş bir argüman için bir istisna fırlatabilirdi. Ancak bu tanımlar ayrı ayrı kontroller gerektiriyordu.
Andy Thomas

3
@BenThurley - Davranış geçmiş ve şimdiki Java özellikleriyle garanti edilir. Bence Luke'un amacı, şimdiki zamanın garantili davranışını belirlemede deneylerin sınırlamalarına değiniyor.
Andy Thomas

267

İlk terim olarak bir sıfır referansı kullanılarak instanceofgetiri false.


268
(Ve şimdi bu soruyu Google'da bulmak 10 saniye sürüyor)
PL_kolek

73

Gerçekten çok iyi bir soru. Sadece kendim için denedim.

public class IsInstanceOfTest {

    public static void main(final String[] args) {

        String s;

        s = "";

        System.out.println((s instanceof String));
        System.out.println(String.class.isInstance(s));

        s = null;

        System.out.println((s instanceof String));
        System.out.println(String.class.isInstance(s));
    }
}

Baskılar

true
true
false
false

JLS / 15.20.2. Tür Karşılaştırma Operatörü örneği

Çalışma zamanında instanceofoperatörün sonucu true, RelationalExpression değerinin olmaması nullve başvurunun a yükseltilmeden ReferenceType'a aktarılabilmesidir ClassCastException. Aksi takdirde sonuç olur false.

API / Sınıf # isInstance (Nesne)

Bu Classnesne bir arabirimi temsil trueediyorsa, belirtilen Objectbağımsız değişkenin sınıfı veya herhangi bir üst sınıfı bu arabirimi uygularsa bu yöntem döndürülür ; falseaksi halde geri döner . Bu Classnesne ilkel bir türü temsil ediyorsa , bu yöntem geri döner false.


Biraz kafa karıştırıcı. "String" yazdığı için s bir String, s boş olduğu için s bir String değil. Öyleyse ne oluyor?
Kai Wang

1
@KaiWang ssadece bir nesne referans değişkendir. Gerçekte var olan bir nesneye ( "") atıfta bulunabilir veya nulldeğişmez bir referansa başvurabilir .
Jin Kwon

Hala kafam karıştı. s artık boş olabilir, ancak yalnızca daha sonra bir String örneğine yönlendirilebilir. Tamsayı gibi gösterilemez. Bu yüzden hala bir String, null bile. Çok mantıklı değil ...
Kai Wang

@KaiWang Değişken türünü gerçek nesnenin türüyle karıştırıyorsunuz. Değişkenler örnek değildir; etkin bir şekilde sadece işaretçilerdir. nullhangi değişkeni gösterirse gösterilsin, string veri değildir. örneğin s instanceof String, aynı değildir field.getType().equals(String.class).
Matthew

@KaiWang Görüúmeye hayal etmek zorunda olduğunu olacak, böylece gerçek değerle değiştirilir alır ve . Bu şekilde düşünmek daha anlamlı olabilir. s instanceof Strings"" instanceof Stringnull instanceof String
Timo Türschmann


16

Tıpkı bir tidbit gibi :

Hatta geri döner .(((A)null)instanceof A)false


(Daktilo yazmak nullşaşırtıcı görünüyorsa, bazen bunu yapmak zorundasınız, örneğin böyle durumlarda:

public class Test
{
  public static void test(A a)
  {
    System.out.println("a instanceof A: " + (a instanceof A));
  }

  public static void test(B b) {
    // Overloaded version. Would cause reference ambiguity (compile error)
    // if Test.test(null) was called without casting.
    // So you need to call Test.test((A)null) or Test.test((B)null).
  }
}

Böylece Test.test((A)null)yazdırılacaktır a instanceof A: false.)


Not: İşe alıyorsanız, lütfen bunu iş görüşmesi sorusu olarak kullanmayın. : D


7

Hayır . Java değişmez bilgisi nullherhangi bir sınıfın örneği değildir. Bu nedenle herhangi bir sınıf örneği olamaz . instanceof ya geri döner falsevetrue bu nedenle <referenceVariable> instanceof <SomeClass>döner falsezaman referenceVariabledeğeri sıfırdır.


5
Bu açıklama garip bir şekilde dairesel geliyor ... ama ne demek istediğini biliyorum :-)
Kris

@Kris ty yorum için ne demek istediğini anladım :). Bir cevap biraz düzenledi :).
Geliştirici Marius Žilėnas

1

instanceofOperatör açık gerekmez nullbir atmaz olarak, çek NullPointerExceptionişlenen ise null.

Çalışma zamanında, instanceofilişkisel ifadenin değeri değilse nullve referans bir sınıf dökümü istisnası yükseltilmeden referans türüne dönüştürülebilirse , operatörün sonucu doğrudur .

İşlenen ise null, instanceofoperatör geri döner falseve bu nedenle açık null kontroller gerekmez.

Aşağıdaki örneği düşünün,

public static void main(String[] args) {
         if(lista != null && lista instanceof ArrayList) {                     //Violation
                System.out.println("In if block");
         }
         else {
                System.out.println("In else block");
         }
}

Doğru kullanımı instanceofaşağıda gösterildiği gibidir,

public static void main(String[] args) {
      
         if(lista instanceof ArrayList){                     //Correct way
                  System.out.println("In if block");
         }
            else {
                 System.out.println("In else block");
         }  
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.