Java中使用的'instanceof'运算符是什么?

时间:2011-09-05 23:28:14

标签: java instanceof

instanceof运算符用于什么?我见过像

这样的东西
if (source instanceof Button) {
    //...
} else {
    //...
}

但这对我来说都没有意义。我已经完成了我的研究,但只提供了一些没有任何解释的例子。

18 个答案:

答案 0 :(得分:217)

instanceof关键字是二元运算符,用于测试对象(实例)是否是给定Type的子类型。

想象:

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

因为AnimalDog的超类型,可能更少“精炼”。

dog instanceof Cat // does not even compile!

这是因为Dog既不是Cat的子类型也不是超类型,也不会实现它。

请注意,上面用于dog的变量属于Object类型。这是为了显示instanceof是一个运行时操作,并将我们带到一个用例:根据运行时的对象类型做出不同的反应。

注意事项:expressionThatIsNull instanceof T对所有类型T都是错误的。

快乐的编码。

答案 1 :(得分:42)

如果表达式的左侧是 右侧的类名实例,则它是一个返回true的运算符。

以这种方式思考。说你街区的所有房屋都是用相同的蓝图建造的。十个房屋(物体),一套蓝图(类定义)。

instanceof是一个很有用的工具,当你有一个对象集合并且你不确定它们是什么时。假设您在表单上有一组控件。您想要读取任何复选框的已检查状态,但是您不能要求普通旧对象检查其已检查状态。相反,你会看到每个对象是否都是一个复选框,如果是,则将其转换为复选框并检查其属性。

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

答案 2 :(得分:28)

this site所述:

  

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

我希望这有帮助!

答案 3 :(得分:14)

如果sourceobject变量,instanceof是检查它是否为Button的一种方式。

答案 4 :(得分:14)

此运算符允许您确定对象的类型。 它返回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

答案 5 :(得分:3)

正如其他答案中所提到的,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.2Java 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); 
    }
}

答案 6 :(得分: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 

    }
}

答案 7 :(得分:1)

大多数人正确地解释了这个问题的“内容”,但是没有人正确地解释了“如何”。

这是一个简单的例子:

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

docs中很好地说明了将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

答案 8 :(得分:1)

可以在等式检查中用作速记。

  

所以这段代码

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

可以写成

if(ob instanceOf ClassA) {
}

答案 9 :(得分:0)

在 JDK 16 中引入了 instanceof 的模式匹配。

之前:

if (obj instanceof StringBuilder) {
  StringBuilder builder = (StringBuilder) obj;
  builder.append("Hello StackOverflow")
}

现在:

if (obj instanceof StringBuilder builder) {
  builder.append("Hello StackOverflow")
}

之前:

public boolean equals(Object o) {
  if (!(o instanceof StringBuilder)) {
    return false;
  }
  StringBuilder other = (StringBuilder) o;
  return //Logic
}

现在:

public boolean equals(Object o) {
  return (o instanceof StringBuilder other)
  //Logic
}

答案 10 :(得分:0)

java instanceof运算符用于测试对象是否是指定类型(类,子类或接口)的实例。

java中的instanceof也称为类型comparison operator,因为它将实例与类型进行比较。它返回truefalse。如果我们将instanceof运算符应用于任何具有null值的变量,它将返回false

在包含JEP 305的JDK 14+中,我们还可以为instanceof做“模式匹配”

模式基本上测试一个值是否具有某种类型,并且在具有匹配类型时可以从该值中提取信息。 模式匹配使系统中的通用逻辑更加清晰有效地表达,即有条件地从对象中删除组件。

在Java 14之前

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

Java 14增强功能

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

我们也可以将类型检查和其他条件结合在一起

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

instanceof中使用模式匹配应减少Java程序中显式强制转换的总数。

PS instanceOf仅在对象不为null时匹配,然后只能将其分配给str

答案 11 :(得分:0)

最好的解释是jls。 始终尝试检查消息来源。在那里,您将获得最佳答案,还有更多。 在此处复制一些部分:

instanceof的RelationalExpression操作数的类型 运算符必须是引用类型或null类型;否则,一个 发生编译时错误。

如果引用类型后面提到了ReferenceType,则是编译时错误。 instanceof运算符不表示可引用的引用类型 (§4.7)。

如果将RelationalExpression强制转换(第15.16节)到ReferenceType 将被拒绝为编译时错误,然后是instanceof 关系表达式同样会产生编译时错误。在这样的 在某种情况下,instanceof表达式的结果永远不会 是的。

答案 12 :(得分:0)

当您想要了解特定对象的实例时,关键字实例会很有用。

假设你是抛出异常,当你有捕获然后执行sum自定义操作然后再按照你的逻辑继续(抛出或记录等)

示例: 1)用户创建了自定义异常“InvalidExtensionsException”并按逻辑

抛出它

2)现在处于阻挡状态 catch(例外e){    如果异常类型为“InvalidExtensionsException”

,则执行sum逻辑
InvalidExtensionsException InvalidException =(InvalidExtensionsException)e;

3)如果您没有检查实例,并且异常类型是Null指针异常,则代码将中断。

所以你的逻辑应该在实例的内部     if(e instanceof InvalidExtensionsException){      InvalidExtensionsException InvalidException =(InvalidExtensionsException)e;     }

上面的例子是错误的编码实践但是这个例子可以帮助你理解它的实例的使用。

答案 13 :(得分:0)

  

instanceof运算符将对象与指定类型进行比较。您可以使用它来测试对象是否是类的实例,子类的实例或实现特定接口的类的实例。

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

答案 14 :(得分:-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);
}
}  

答案 15 :(得分:-1)

您可以使用Map在

的实例上进行更高的抽象
actions.put(String.class, new Consumer<String>() {
        @Override
        public void accept(String s) {
           System.out.println("action for String");       
        }
    };

然后让这样的地图添加一些动作:

actions.get(someObject).accept(someObject)

然后拥有一个未知类型的对象,您可以从该地图获得特定的操作:

 xtype: 'grid',
 store: {
        type: 'webapi',
        api: {
            read: 'api/Report/GetIfo'
        },
        autoLoad: true,
    },
 columns: [    
        { header: 'Name', dataIndex: 'first_name'}
    ], 
    selModel: {
                selType: 'checkboxmodel',    
                //dataIndex:'flag',
                //showHeaderCheckbox: true
            }

答案 16 :(得分:-2)

instanceof运算符用于检查对象是否是指定类型的实例。 (类或子类或接口)。

instanceof也称为类型比较运算符,因为它将实例与类型进行比较。它返回true或false。

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

如果我们将instanceof运算符应用于任何具有null值的变量,则返回false。

答案 17 :(得分:-2)

非常简单的代码示例:

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

这里要小心。在上面的示例中,如果Class1是Object,则第一个比较将始终为true。所以,就像异常一样,等级顺序很重要!