Java'da kullanılan 'instanceof' operatörü nedir?


163

instanceofOperatör ne için kullanılır? Gibi şeyler gördüm

if (source instanceof Button) {
    //...
} else {
    //...
}

Ama bunların hiçbiri bana mantıklı gelmedi. Araştırmamı yaptım, ancak açıklama yapmadan sadece örneklerle geldim.


38
Burada soru sormanın yanlış bir yanı yok, ancak Java öğreniyorsanız bir kitap almak isteyebilirsiniz. İyi bir Java kitabı bu sorunun cevabına ve bir sonraki 1000'e sahip olacaktır.
Başkan James K. Polk

Böyle bir operatörün birçok özel kullanımı vardır. Sizin için anlamlı olmayan örneklerden birinin açıklanmasını isterse, bu özel bir soru olurdu.
Raedwald

2
Aşağıdaki cevaplar doğrudur, ancak instanceof'in 10 üzerinden 9 kez aşırı kullanımlı bir operatör olduğunu ve bunun yerine polimorfizmin (her zaman değil, sıklıkla) uygun bir şekilde kullanılabileceğini unutmayın
Richard Tingle

Richard'dan bir tane daha ileri giderdim: ASLA geçerli bir instanceof kullanımı görmedim. Sadece kötü tasarlanmış kodun üstündeki hızlı kesmek için kullanışlıdır. OOP'dan hoşlanmıyorsanız, başka bir dilde yazın (bolca var). Hemen "hayır" deyin!
Scott Biggs

5
@ScottBiggs instanceofGeçersiz kılma sırasında iyi bir alternatif var mı equals?
Ben Aaronson

Yanıtlar:


228

instanceofanahtar kelime, bir nesnenin (örnek) belirli bir Türün alt türü olup olmadığını sınamak için kullanılan bir ikili işleçtir.

Hayal etmek:

interface Domestic {}
class Animal {}
class Dog extends Animal implements Domestic {}
class Cat extends Animal implements Domestic {}

Şununla oluşturulmuş bir dog nesne düşünün Object dog = new Dog(), sonra:

dog instanceof Domestic // true - Dog implements Domestic
dog instanceof Animal   // true - Dog extends Animal
dog instanceof Dog      // true - Dog is Dog
dog instanceof Object   // true - Object is the parent type of all objects

Ancak Object animal = new Animal();,

animal instanceof Dog // false

çünkü Animalbir süpertip Dogve muhtemelen daha az "rafine" dir.

Ve,

dog instanceof Cat // does not even compile!

Bunun nedeni Dog, ne bir alt tür ne de bir üst tür Catdeğildir ve bunu da uygulamaz.

dogYukarıda kullanılan değişkenin tür olduğuna dikkat edin Object. Bu, instanceofbir çalışma zamanı işlemidir ve bizi bir / use durumuna getirir: çalışma zamanında bir nesne türüne göre farklı tepki vermek .

Unutulmaması gerekenler: expressionThatIsNull instanceof TTüm Türler için yanlıştır T.

Mutlu kodlama.


14
Sadece denedim - Object dog = new Dog(); System.out.println(dog instanceof Cat);. Bu sadece iyi derler ve yazdırır false. Derleyicinin dogbir kedi olamayacağı derleme süresine izin verilmez (
JLS'deki

@ErwinBolwidt Bunu denediğinizde bir hata yaptınız. Merak eden herkes için: JLS Bölüm 15.20.2 aradığınız bölümdür. Minimum çalışmayan bir örnek için:boolean b = "foo" instanceof Integer;
Felix S

3
@FelixS Cevabı tekrar okumalısınız. Cevap yaklaşık Object indirect = ...; if (indirect instanceof Something). Sanki if (literal instanceof Something)varsayıyor gibisin.
Erwin Bolwidt

1
@ErwinBolwidt Oh, doğru, Object dogparçayı atlamalıydım . Benim hatam!
Felix S

dog instanceof Cat // does not even compile!(çünkü bir sınıftır). Bir Catarayüz olsaydı derlenirdi.
Hamza Belmellouki

44

İfadenin sol tarafı sağ taraftaki sınıf adının bir örneğiyse true döndüren bir işleçtir .

Bu şekilde düşünün. Diyelim ki bloğunuzdaki tüm evler aynı planlardan inşa edildi. On ev (nesne), bir dizi plan (sınıf tanımı).

instanceofnesnelerin bir koleksiyonuna sahip olduğunuzda ve bunların ne olduğundan emin değilseniz kullanışlı bir araçtır. Diyelim ki bir form üzerinde kontroller koleksiyonunuz var. Herhangi bir onay kutusunun işaretli durumunu okumak istiyorsunuz, ancak eski bir düz nesneden işaretli durumunu isteyemezsiniz. Bunun yerine, her nesnenin bir onay kutusu olup olmadığını görürsünüz ve varsa bir onay kutusuna yayınlar ve özelliklerini kontrol edersiniz.

if (obj instanceof Checkbox)
{
    Checkbox cb = (Checkbox)obj;
    boolean state = cb.getState();
}

15
Yani, kullanmak instanceofmahremiyetin güvenliğini sağlayabilir.
Raedwald

29

Bu sitede açıklandığı gibi :

instanceofBir nesnenin, belirli tipte olursa operatör testi için kullanılabilir ...

if (objectReference instanceof type)

Kısa bir örnek:

String s = "Hello World!"
return s instanceof String;
//result --> true

Ancak, instanceofbir boş başvuru değişkeni / ifadesine uygulamak false değerini döndürür.

String s = null;
return s instanceof String;
//result --> false

Bir alt sınıf, üst sınıfının bir 'türü' olduğundan, bunu instanceofdoğrulamak için ...

class Parent {
    public Parent() {}
}

class Child extends Parent {
    public Child() {
        super();
    }
}

public class Main {
    public static void main(String[] args) {
        Child child = new Child();
        System.out.println( child instanceof Parent );
    }
}
//result --> true

Umarım bu yardımcı olur!


15

Bu operatör, bir nesnenin türünü belirlemenizi sağlar. Döndürürboolean değer .

Örneğin

package test;

import java.util.Date;
import java.util.Map;
import java.util.HashMap;

public class instanceoftest
{
    public static void main(String args[])
    {
        Map m=new HashMap();
        System.out.println("Returns a boolean value "+(m instanceof Map));
        System.out.println("Returns a boolean value "+(m instanceof HashMap));
        System.out.println("Returns a boolean value "+(m instanceof Object));
        System.out.println("Returns a boolean value "+(m instanceof Date));
    }
} 

çıktı:

Returns a boolean value true
Returns a boolean value true
Returns a boolean value true
Returns a boolean value false

14

Eğer sourcebir olan objectdeğişken, instanceoföyle bir olmadığını görmek için kontrol bir yoludur Buttonya da değil.


5

Diğer cevaplarda belirtildiği gibi, kurallı tipik kullanımı, instanceofbir tanımlayıcının daha spesifik bir türe atıfta bulunup bulunmadığını kontrol etmektir. Misal:

Object someobject = ... some code which gets something that might be a button ...
if (someobject instanceof Button) {
    // then if someobject is in fact a button this block gets executed
} else {
    // otherwise execute this block
}

Ancak, sol taraftaki ifadenin türünün sağ taraftaki ifadenin üst türü olması gerektiğini unutmayın (bkz. JLS 15.20.2 ve Java Puzzlers, # 50, s . 114 ). Örneğin, aşağıdakiler derlenemez:

public class Test {
    public static void main(String [] args) {
        System.out.println(new Test() instanceof String); // will fail to compile
    }
}

Bu ileti ile derlenemez:

Test.java:6: error: inconvertible types
        System.out.println(t instanceof String);
                       ^
  required: String
  found:    Test
1 error

Gibi Testbir üst sınıf değildir String. OTOH, bu mükemmel bir şekilde derlenir ve falsebeklendiği gibi yazdırılır :

public class Test {
    public static void main(String [] args) {
        Object t = new Test();
        // compiles fine since Object is a parent class to String
        System.out.println(t instanceof String); 
    }
}

Spesifikasyona bağladığınız için teşekkürler!
jpaugh

1
public class Animal{ float age; }

public class Lion extends Animal { int claws;}

public class Jungle {
    public static void main(String args[]) {

        Animal animal = new Animal(); 
        Animal animal2 = new Lion(); 
        Lion lion = new Lion(); 
        Animal animal3 = new Animal(); 
        Lion lion2 = new Animal();   //won't compile (can't reference super class object with sub class reference variable) 

        if(animal instanceof Lion)  //false

        if(animal2 instanceof Lion)  //true

        if(lion insanceof Lion) //true

        if(animal3 instanceof Animal) //true 

    }
}

1

Eşitlik kontrolünde stenografi olarak kullanılabilir.

Yani bu kod

if(ob != null && this.getClass() == ob.getClass) {
}

Olarak yazılabilir

if(ob instanceOf ClassA) {
}

1

Çoğu insan bu sorunun "Ne" sini doğru bir şekilde açıkladı, ama hiç kimse "Nasıl" sını doğru bir şekilde açıklamadı.

İşte basit bir örnek:

String s = new String("Hello");
if (s instanceof String) System.out.println("s is instance of String"); // True
if (s instanceof Object) System.out.println("s is instance of Object"); // True
//if (s instanceof StringBuffer) System.out.println("s is instance of StringBuffer"); // Compile error
Object o = (Object)s;
if (o instanceof StringBuffer) System.out.println("o is instance of StringBuffer"); //No error, returns False
else System.out.println("Not an instance of StringBuffer"); // 
if (o instanceof String) System.out.println("o is instance of String"); //True

Çıktılar:

s is instance of String
s is instance of Object
Not an instance of StringBuffer
o is instance of String

sStringBuffer ile karşılaştırılırken derleyici hatasının nedeni dokümanlarda iyi açıklanmıştır :

Bir nesnenin bir sınıf örneği mi, alt sınıf örneği mi yoksa belirli bir arabirimi uygulayan bir sınıf örneği mi olduğunu sınamak için kullanabilirsiniz.

LHS, RHS örneği veya RHS uygulayan veya RHS'yi genişleten bir Sınıf örneği olmalıdır.

O halde instanceof kullanımı nasıl kullanılır?
Her Sınıf Nesneyi genişlettiğinden, nesneye LHS yazarak her zaman sizin lehinize çalışacaktır:

String s = new String("Hello");
if ((Object)s instanceof StringBuffer) System.out.println("Instance of StringBuffer"); //No compiler error now :)
else System.out.println("Not an instance of StringBuffer");

Çıktılar:

Not an instance of StringBuffer

Son örnekte, neden "StringBuffer örneği değil" döndürüyor? LHS üzerindeki Object'e s yazdığınızdan ve bunun RHS örneği olup olmadığını kontrol ettiğinizden, if ((Object)s instanceof StringBuffer) System.out.println("Instance of StringBuffer"); //shouldn't this be trues Object'e yazıyoruz.
sofs1

S String nesnesine bir başvuru olduğundan (Java, C ++ 'dan farklı olarak dinamik polimorfizm kullanır) ve String, StringBuffer öğesinin bir alt sınıfı değildir.
sziraqui


0

Belirli bir nesnenin örneğini bilmek istediğinizde anahtar kelime örneği yardımcı olur.

İstisna attığınızı ve yakaladığınız zaman toplam özel işlem gerçekleştirdiğinizi ve ardından mantığınıza göre (fırlatma veya log vb.) Devam edin.

Örnek: 1) Kullanıcı "InvalidExtensionsException" özel istisnası yarattı ve mantığa göre attı

2) Şimdi catch blok catch'te (Exception e) {istisna türü "InvalidExtensionsException" ise toplam mantığı gerçekleştirin

InvalidExtensionsException InvalidException =(InvalidExtensionsException)e;

3) örneğini kontrol etmiyorsanız ve istisna türü Boş gösterici istisnası ise kodunuz bozulur.

Bu nedenle, mantığınızın if (e IntanExtensionsException örneği) {InvalidExtensionsException InvalidException = (InvalidExtensionsException) e; }

Yukarıdaki örnek yanlış kodlama uygulamasıdır. Ancak bu örnek, bunun örneğini kullanmayı anlamanıza yardımcı olur.


0

En iyi açıklama jls . Her zaman kaynağın ne dediğini kontrol etmeye çalışın. Orada en iyi yanıtı ve çok daha fazlasını alacaksınız. Bazı parçaları burada çoğaltma:

İnstanceof operatörünün RelationalExpression işleneninin türü, bir başvuru türü veya boş tür olmalıdır; aksi halde derleme zamanı hatası oluşur.

İnstanceof işlecinden sonra bahsedilen ReferenceType, yeniden kullanılabilir bir başvuru türünü belirtmiyorsa, derleme zamanı hatasıdır (§4.7).

ReferenceType'a RelationalExpression öğesinin bir dökümü (§15.16) derleme zamanı hatası olarak reddedilirse, ilişkisel ifade örneği de derleme zamanı hatası üretir. Böyle bir durumda, ifade örneğinin sonucu asla doğru olamaz.


0

Java instanceof işleci, nesnenin belirtilen türde (sınıf veya alt sınıf veya arabirim) bir örneği olup olmadığını sınamak için kullanılır.

comparison operatorJava'daki instanceof, örneği türle karşılaştırdığı için tür olarak da bilinir . Ya trueda döner false. instanceofİşleci nulldeğeri olan herhangi bir değişkenle uygularsak,false .

JEP 305 içeren JDK 14+ sürümünden ayrıca "Pattern Matching"instanceof

Desenler temel olarak bir değerin belirli bir türe sahip olduğunu test eder ve eşleşen tipe sahip olduğunda değerden bilgi çıkarabilir. Örüntü eşleme, bir sistemdeki ortak mantığın, bileşenlerin nesnelerden koşullu olarak kaldırılması konusunda daha açık ve etkili bir şekilde ifade edilmesini sağlar.

Java öncesi 14

if (obj instanceof String) {
    String str = (String) obj; // need to declare and cast again the object
    .. str.contains(..) ..
}else{
     str = ....
}

Java 14 geliştirmeleri

if (!(obj instanceof String str)) {
    .. str.contains(..) .. // no need to declare str object again with casting
} else {
    .. str....
}

Ayrıca tip kontrolü ve diğer koşulları bir araya getirebiliriz

if (obj instanceof String str && str.length() > 4) {.. str.contains(..) ..}

Kalıp eşleşmesinin kullanılması, instanceofJava programlarındaki genel açık döküm sayısını azaltmalıdır.

PS : instanceOfyalnızca nesne boş olmadığında eşleşir, ancak yalnızca atanabilir str.


-1
class Test48{
public static void main (String args[]){
Object Obj=new Hello();
//Hello obj=new Hello;
System.out.println(Obj instanceof String);
System.out.println(Obj instanceof Hello);
System.out.println(Obj instanceof Object);
Hello h=null;
System.out.println(h instanceof Hello);
System.out.println(h instanceof Object);
}
}  

1
Kod yanıtlarını yalnızca StackOverflow'da yayınlamayın. Lütfen devam edin ve bir açıklama ekleyin.
L. Guthardt

-2

Çok basit kod örneği:

If (object1 instanceof Class1) {
   // do something
} else if (object1 instanceof Class2) {
   // do something different
}

Burada dikkatli ol. Yukarıdaki örnekte, Class1 Object ise, ilk karşılaştırma her zaman doğru olacaktır. Yani, istisnalar gibi, hiyerarşik düzen önemlidir!


-2

Harita üzerinde daha yüksek soyutlama yapmak için kullanabilirsiniz.

private final Map<Class, Consumer<String>> actions = new HashMap<>();

Sonra böyle bir haritaya bazı eylemler eklemek:

actions.put(String.class, new Consumer<String>() {
        @Override
        public void accept(String s) {
           System.out.println("action for String");       
        }
    };

Ardından, bilinmeyen türde bir Nesneye sahip olduğunuzda, bu haritadan belirli bir işlem yapabilirsiniz:

actions.get(someObject).accept(someObject)

-2

İnstanceof operatörü, nesnenin belirtilen türde bir örnek olup olmadığını kontrol etmek için kullanılır. (sınıf veya alt sınıf veya arayüz).

İnstanceof, tür ile tür karşılaştırdığından tür karşılaştırma operatörü olarak da bilinir. Doğru veya yanlış döndürür.

class Simple1 {  
public static void main(String args[]) {  
Simple1 s=new Simple1();  
System.out.println(s instanceof Simple1); //true  
}  
}  

İnstanceof operatörünü null değeri olan herhangi bir değişkenle uygularsak, false değerini döndürür.

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.