Для чего используется оператор instanceof в Java? - PullRequest
152 голосов
/ 06 сентября 2011

Для чего используется оператор instanceof? Я видел такие вещи, как

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

Но ничего из этого не имело для меня смысла. Я провел свое исследование, но нашел только примеры без каких-либо объяснений.

Ответы [ 15 ]

218 голосов
/ 06 сентября 2011
Ключевое слово

instanceof представляет собой двоичный оператор , используемый для проверки, является ли объект (экземпляр) подтипом данного Типа.

Представьте себе:

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

Представьте себе dog объект , созданный с помощью Object dog = new Dog(), затем:

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

Однако, с Object animal = new Animal();,

animal instanceof Dog // false

, потому что Animal является супертипом Dog и, возможно, менее "изысканным".

И

dog instanceof Cat // does not even compile!

Это потому, что Dog не является ни подтипом, ни супертипом Cat, и он также не реализует его.

Обратите внимание, что переменная, используемая для dog выше, имеет тип Object. Это показывает, что instanceof является операцией времени выполнения и приводит нас к / сценарию использования: , чтобы по-разному реагировать на тип объекта во время выполнения .

На заметку: expressionThatIsNull instanceof T неверно для всех типов T.

Удачного кодирования.

42 голосов
/ 06 сентября 2011

Это оператор, который возвращает истину, если левая сторона выражения - это экземпляр имени класса с правой стороны.

Думайте об этом так. Скажем, все дома в вашем квартале были построены из одинаковых чертежей. Десять домов (объектов), один набор чертежей (определение класса).

instanceof - это полезный инструмент, когда у вас есть коллекция объектов, и вы не знаете, что это такое. Допустим, у вас есть коллекция элементов управления в форме. Вы хотите прочитать проверенное состояние всех имеющихся флажков, но вы не можете запросить простой старый объект для его проверенного состояния. Вместо этого вы увидите, является ли каждый объект флажком, и если он есть, приведите его к флажку и проверьте его свойства.

if (obj instanceof Checkbox)
{
    Checkbox cb = (Checkbox)obj;
    boolean state = cb.getState();
}
28 голосов
/ 06 сентября 2011

Как описано на этом сайте :

Оператор instanceof может использоваться для проверки того, является ли объект определенный тип ...

if (objectReference instanceof type)

Быстрый пример:

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

Однако, применение instanceof к нулевой ссылочной переменной / выражению возвращает false.

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

Поскольку подкласс является «типом» своего суперкласса, вы можете использовать instanceof чтобы проверить это ...

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

Надеюсь, это поможет!

14 голосов
/ 08 мая 2014

Этот оператор позволяет вам определить тип объекта. Возвращает значение boolean.

Например

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

вывод:

Returns a boolean value true
Returns a boolean value true
Returns a boolean value true
Returns a boolean value false
14 голосов
/ 06 сентября 2011

Если source - это переменная object, instanceof - это способ проверить, является ли она Button или нет.

3 голосов
/ 14 декабря 2013

Как упоминалось в других ответах, каноническое типичное использование instanceof предназначено для проверки того, относится ли идентификатор к более конкретному типу. Пример:

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
}

Обратите внимание, что тип левого выражения должен быть родительским типом правого выражения (см. JLS 15.20.2 и Java Puzzlers, # 50, pp114 ). Например, следующее не удастся скомпилировать:

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

Это не скомпилируется с сообщением:

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

Поскольку Test не является родительским классом String. OTOH, это прекрасно компилируется и печатает false, как и ожидалось:

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); 
    }
}
1 голос
/ 22 июля 2018

Большинство людей правильно объяснили «Что» в этом вопросе, но никто не объяснил «Как» правильно.

Итак, вот простая иллюстрация:

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

Выходы:

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

Причина ошибки компилятора при сравнении s со StringBuffer хорошо объяснена в документах :

Вы можете использовать его, чтобы проверить, является ли объект экземпляром класса, экземпляром подкласса или экземпляром класса, который реализует определенный интерфейс.

, что подразумевает, что LHS должен быть либо экземпляром RHS, либо класса, который либо реализует RHS, либо расширяет RHS.

Как тогда использовать instanceof?
Поскольку каждый класс расширяет объект, приведение типов LHS к объекту всегда будет работать в вашу пользу:

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

Выходы:

Not an instance of StringBuffer
1 голос
/ 06 сентября 2016

Может использоваться как сокращение в проверке равенства.

Итак, этот код

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

Может быть записано как

if(ob instanceOf ClassA) {
}
1 голос
/ 13 декабря 2014
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 

    }
}
0 голосов
/ 09 июля 2018
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);
}
}  
...