Untuk apa operator 'instanceof' digunakan di Jawa?

163

Untuk apa instanceofoperator itu digunakan? Saya pernah melihat hal-hal seperti

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

Tetapi tidak ada yang masuk akal bagi saya. Saya sudah melakukan penelitian, tetapi muncul hanya dengan contoh tanpa penjelasan.

Ben
sumber
38
Tidak ada yang salah dengan mengajukan pertanyaan di sini, tetapi jika Anda belajar Java Anda mungkin ingin mendapatkan buku. Buku Java mana pun yang layak akan memiliki jawaban untuk pertanyaan ini dan 1000 buku berikutnya yang akan Anda miliki.
Presiden James K. Polk
Operator seperti itu memiliki banyak kegunaan khusus. Ini akan menjadi pertanyaan khusus jika meminta penjelasan dari salah satu contoh yang tidak masuk akal bagi Anda.
Raedwald
2
Jawaban di bawah ini benar, namun perhatikan bahwa instanceof adalah operator yang digunakan berlebihan 9 kali dari 10 dapat digantikan dengan penggunaan polimorfisme yang tepat (tidak selalu, tetapi sering)
Richard Tingle
Saya akan melangkah lebih jauh dari Richard: Saya belum pernah melihat penggunaan instanceof yang valid. Ini hanya berguna untuk peretasan cepat di atas kode yang dirancang dengan buruk. Jika Anda tidak menyukai OOP, tulis dalam bahasa lain (ada banyak). Katakan saja, "tidak" untuk contoh!
Scott Biggs
5
@ScottBiggs Apakah ada alternatif yang baik instanceofketika menimpa equals?
Ben Aaronson

Jawaban:

228

instanceofkata kunci adalah operator biner yang digunakan untuk menguji apakah suatu objek (instance) adalah subtipe dari Tipe yang diberikan.

Membayangkan:

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

Bayangkan sebuah dog objek , dibuat dengan Object dog = new Dog(), lalu:

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

Namun, dengan Object animal = new Animal();,

animal instanceof Dog // false

karena Animalmerupakan supertipe Dogdan mungkin kurang "halus".

Dan,

dog instanceof Cat // does not even compile!

Ini karena Dogbukan subtipe atau supertipe Cat, dan juga tidak menerapkannya.

Perhatikan bahwa variabel yang digunakan untuk di dogatas adalah tipe Object. Ini untuk menunjukkan instanceofadalah operasi runtime dan membawa kita ke / use case: untuk bereaksi secara berbeda berdasarkan jenis objek saat runtime .

Hal yang perlu diperhatikan: expressionThatIsNull instanceof Tsalah untuk semua Jenis T.

Selamat coding.

Cache Staheli
sumber
14
Saya baru saja mencoba - Object dog = new Dog(); System.out.println(dog instanceof Cat);. Ini mengkompilasi dengan baik dan mencetak false. Kompiler tidak diperbolehkan menentukan pada waktu kompilasi yang dogtidak bisa menjadi Kucing (sesuai aturan dalam JLS)
Erwin Bolwidt
@ ErwinBolwidt Anda membuat kesalahan ketika Anda mencobanya. Untuk siapa pun yang bertanya-tanya: JLS Bagian 15.20.2 adalah yang Anda cari. Untuk contoh non-kerja yang minimal:boolean b = "foo" instanceof Integer;
Felix S
3
@ Feliks Anda harus membaca jawabannya lagi. Jawabannya adalah tentang Object indirect = ...; if (indirect instanceof Something). Ini bukan tentang if (literal instanceof Something)seperti yang Anda asumsikan.
Erwin Bolwidt
1
@ ErwinBolwidt Oh, benar, aku pasti melewatkan Object dogbagian itu. Salahku!
Felix S
dog instanceof Cat // does not even compile!(karena ini adalah kelas). Jika Catsebuah antarmuka maka itu akan dikompilasi.
Hamza Belmellouki
44

Ini adalah operator yang mengembalikan true jika sisi kiri ekspresi adalah turunan dari nama kelas di sisi kanan.

Pikirkan seperti ini. Katakanlah semua rumah di blok Anda dibangun dari cetak biru yang sama. Sepuluh rumah (objek), satu set cetak biru (definisi kelas).

instanceofadalah alat yang berguna ketika Anda memiliki koleksi benda dan Anda tidak yakin benda apa itu. Katakanlah Anda memiliki koleksi kontrol pada formulir. Anda ingin membaca keadaan dicentang dari kotak centang apa pun yang ada, tetapi Anda tidak bisa meminta objek tua polos untuk keadaan dicentangnya. Sebagai gantinya, Anda akan melihat apakah setiap objek adalah kotak centang, dan jika ya, masukkan ke kotak centang dan periksa propertinya.

if (obj instanceof Checkbox)
{
    Checkbox cb = (Checkbox)obj;
    boolean state = cb.getState();
}
Michael Petrotta
sumber
15
Artinya, menggunakan instanceofbisa membuatnya aman untuk downcast.
Raedwald
29

Seperti yang dijelaskan di situs ini :

The instanceofoperator dapat digunakan untuk menguji apakah suatu objek dari jenis tertentu ...

if (objectReference instanceof type)

Contoh cepat:

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

Namun, menerapkan instanceofvariabel referensi nol / ekspresi menghasilkan false.

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

Karena subkelas adalah 'jenis' dari superclassnya, Anda dapat menggunakan instanceofuntuk memverifikasi ini ...

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

Saya harap ini membantu!

fireshadow52
sumber
15

Operator ini memungkinkan Anda untuk menentukan jenis objek. Ia mengembalikan aboolean nilai.

Sebagai contoh

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));
    }
} 

outputnya adalah:

Returns a boolean value true
Returns a boolean value true
Returns a boolean value true
Returns a boolean value false
Purendra Agrawal
sumber
14

Jika sourceadalah objectvariabel, instanceofadalah cara memeriksa untuk melihat apakah itu adalah Buttonatau tidak.

Daniel A. White
sumber
4

Seperti disebutkan dalam jawaban lain, penggunaan tipikal kanonik instanceofadalah untuk memeriksa apakah pengidentifikasi mengacu pada tipe yang lebih spesifik. Contoh:

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
}

Namun perhatikan, bahwa jenis ekspresi tangan kiri haruslah tipe induk dari ekspresi tangan kanan (lihat JLS 15.20.2 dan Java Puzzlers, # 50, pp114 ). Misalnya, berikut ini akan gagal dikompilasi:

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

Ini gagal dikompilasi dengan pesan:

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

As Testbukan kelas induk dari String. OTOH, ini mengkompilasi dengan sempurna dan mencetak falseseperti yang diharapkan:

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); 
    }
}
Adam Parkin
sumber
Terima kasih telah menautkan ke spec!
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 

    }
}
bangbang
sumber
1

Dapat digunakan sebagai steno dalam pemeriksaan kesetaraan.

Jadi kode ini

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

Dapat ditulis sebagai

if(ob instanceOf ClassA) {
}
mirmdasif
sumber
1

Kebanyakan orang dengan benar menjelaskan "Apa" dari pertanyaan ini tetapi tidak ada yang menjelaskan "Bagaimana" dengan benar.

Jadi inilah ilustrasi sederhana:

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

Output:

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

Alasan kesalahan kompiler ketika membandingkan sdengan StringBuffer dijelaskan dengan baik dalam dokumen :

Anda dapat menggunakannya untuk menguji apakah suatu objek adalah turunan dari kelas, turunan dari subkelas, atau turunan dari kelas yang mengimplementasikan antarmuka tertentu.

yang menyiratkan LHS harus berupa turunan dari RHS atau dari Kelas yang mengimplementasikan RHS atau memperluas RHS.

Bagaimana cara menggunakan instanceof itu?
Karena setiap Kelas memperluas Objek, ketik-casting LHS ke objek akan selalu bekerja sesuai keinginan Anda:

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");

Output:

Not an instance of StringBuffer
sziraqui
sumber
Pada contoh terakhir, mengapa ia mengembalikan "Bukan instance dari StringBuffer"? Karena Anda mengetikkan s ke Objek pada LHS dan memeriksa apakah itu merupakan instance dari RHS if ((Object)s instanceof StringBuffer) System.out.println("Instance of StringBuffer"); //shouldn't this be true,, karena kami mengetikkan s ke Objek?
sofs1
Karena s adalah referensi ke objek String (Java menggunakan polimorfisme dinamis tidak seperti C ++) dan String bukan subkelas dari StringBuffer.
sziraqui
0

Instance dari operator membandingkan suatu objek dengan tipe yang ditentukan. Anda dapat menggunakannya untuk menguji apakah suatu objek adalah turunan dari kelas, turunan dari subkelas, atau turunan dari kelas yang mengimplementasikan antarmuka tertentu.

http://download.oracle.com/javase/tutorial/java/nutsandbolts/op2.html

Benjamin Udink sepuluh Cate
sumber
0

Instance dari kata kunci sangat membantu ketika Anda ingin mengetahui instance objek tertentu.

Misalkan Anda melempar pengecualian dan ketika Anda sudah menangkap maka lakukan operasi penjumlahan penjumlahan dan kemudian lanjutkan kembali sesuai logika Anda (melempar atau mencatat dll)

Contoh: 1) Pengguna membuat pengecualian khusus "InvalidExtensionsException" dan membuangnya sesuai logika

2) Sekarang di catch block catch (Exception e) {melakukan logika penjumlahan jika tipe pengecualian adalah "InvalidExtensionsException"

InvalidExtensionsException InvalidException =(InvalidExtensionsException)e;

3) Jika Anda tidak memeriksa turunan dari dan tipe pengecualian adalah Null pointer exception, kode Anda akan rusak.

Jadi logika Anda harus berada di dalam instance of if (misalnya instance InvalidExtensionsException) {InvalidExtensionsException InvalidException = (InvalidExtensionsException) e; }

Contoh di atas adalah praktik pengkodean yang salah. Namun contoh ini membantu Anda untuk memahami penggunaan instance itu.

vaquar khan
sumber
0

Penjelasan terbaik adalah jls . Selalu coba periksa apa yang dikatakan sumber. Di sana Anda akan mendapatkan jawaban terbaik dan banyak lagi. Mereproduksi beberapa bagian di sini:

Jenis operan RelationalExpression dari instanceof operator harus berupa tipe referensi atau tipe nol; jika tidak, kesalahan waktu kompilasi terjadi.

Ini adalah kesalahan waktu kompilasi jika ReferenceType yang disebutkan setelah instanceof operator tidak menunjukkan tipe referensi yang dapat diverifikasi (§4.7).

Jika gips (§15.16) dari RelationalExpression ke ReferenceType akan ditolak sebagai kesalahan waktu kompilasi, maka instance ekspresi relasional juga menghasilkan kesalahan waktu kompilasi. Dalam situasi seperti itu, hasil dari ekspresi tidak akan pernah benar.

nanosoft
sumber
0

instanceofOperator java digunakan untuk menguji apakah objek adalah turunan dari tipe yang ditentukan (kelas atau subkelas atau antarmuka).

Instanceof di java juga dikenal sebagai tipe comparison operatorkarena membandingkan instance dengan type. Ia mengembalikan salah satu trueatau false. Jika kami menerapkan instanceofoperator dengan variabel apa pun yang memiliki nullnilai, ia akan kembali false.

Dari JDK 14+ yang termasuk JEP 305 kita juga dapat melakukan "Pencocokan Pola" untukinstanceof

Pola pada dasarnya menguji bahwa suatu nilai memiliki tipe tertentu, dan dapat mengekstraksi informasi dari nilai tersebut ketika memiliki tipe yang cocok. Pencocokan pola memungkinkan ekspresi yang lebih jelas dan efisien dari logika umum dalam suatu sistem, yaitu penghapusan komponen dari objek secara bersyarat.

Sebelum Jawa 14

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

Java 14 perangkat tambahan

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

Kami juga dapat menggabungkan pemeriksaan tipe dan kondisi lainnya

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

Penggunaan pencocokan pola instanceofharus mengurangi jumlah keseluruhan gips eksplisit dalam program Java.

PS : instanceOfhanya akan cocok ketika objek tidak nol, maka hanya itu yang dapat ditugaskan str.

Bhanu Hoysala
sumber
-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);
}
}  
sajid sadiq
sumber
1
Jangan mengeposkan jawaban hanya kode di StackOverflow. Silakan lanjutkan dan tambahkan penjelasan.
L. Guthardt
-2

Contoh kode yang sangat sederhana:

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

Hati-hati di sini. Dalam contoh di atas, jika Class1 adalah Object, perbandingan pertama akan selalu benar. Jadi, seperti halnya dengan pengecualian, tatanan hierarkis juga penting!

mjuarez
sumber
-2

Anda dapat menggunakan Peta untuk membuat abstraksi yang lebih tinggi pada contoh

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

Kemudian, minta peta semacam itu menambahkan beberapa tindakan:

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

Kemudian memiliki Objek dengan tipe yang tidak dikenal, Anda bisa mendapatkan tindakan spesifik dari peta itu:

actions.get(someObject).accept(someObject)
tomekl007
sumber
-2

Instance dari operator digunakan untuk memeriksa apakah objek adalah turunan dari tipe yang ditentukan. (kelas atau subkelas atau antarmuka).

Instanceof juga dikenal sebagai operator perbandingan tipe karena ia membandingkan instance dengan type. Ia mengembalikan benar atau salah.

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

Jika kita menerapkan instanceof operator dengan variabel apa pun yang memiliki nilai nol, ia mengembalikan false.

Viraj Pai
sumber