繁体   English   中英

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

[英]What is the 'instanceof' operator used for in Java?

instanceof运算符的用途是什么? 我见过类似的东西

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

但这些对我来说都没有意义。 我做了我的研究,但只提出了没有任何解释的例子。

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

想象:

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

想象一个用Object dog = new Dog()创建的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都是假的。

快乐编码。

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

这样想想。 假设您所在街区的所有房屋都是根据相同的蓝图建造的。 十个房子(对象),一套蓝图(类定义)。

当您拥有一组对象并且不确定它们是什么时, instanceof是一个有用的工具。 假设您有一个窗体上的控件集合。 您想读取任何复选框的已选中状态,但您不能向普通旧对象询问其已选中状态。 相反,您将查看每个对象是否是一个复选框,如果是,则将其转换为复选框并检查其属性。

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

本网站所述

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

我希望这有帮助!

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

如果source是一个object变量, instanceof是一种检查它是否是Button

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

    }
}

可用作等式检查的速记。

所以这段代码

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

可以写成

if(ob instanceOf ClassA) {
}
 

大多数人都正确解释了这个问题的“什么”,但没有人正确解释“如何”。

所以这里有一个简单的说明:

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 进行比较时编译器错误的原因在docs 中有很好的解释:

您可以使用它来测试对象是类的实例、子类的实例还是实现特定接口的类的实例。

这意味着 LHS 必须是 RHS 的实例或实现 RHS 或扩展 RHS 的类。

那怎么用instanceof呢?
由于每个类都扩展了 Object,因此将 LHS 类型转换为 object 将始终对您有利:

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

当您想知道特定对象的实例时,关键字的实例很有用。

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

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

2) 现在在 catch 块中 catch (Exception e) { 如果异常类型是“InvalidExtensionsException”,则执行求和逻辑

InvalidExtensionsException InvalidException =(InvalidExtensionsException)e;

3) 如果您不检查实例且异常类型为空指针异常,您的代码将中断。

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

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

最好的解释是jls 始终尝试检查消息来源所说的内容。 在那里你会得到最好的答案以及更多。 在这里复制一些部分:

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

如果 instanceof 运算符之后提到的 ReferenceType 不表示可具体化的引用类型(第 4.7 节),则会出现编译时错误。

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

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只会在对象不为空时匹配,然后才可以分配给str

在 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
}

当 object(listObj) 中存在的元素类型在运行时未知时,也可以使用instanceof运算符。 在这些情况下, instanceof 运算符可用于确定元素类型,并将有助于根据需求进一步进行。

例如 :

   String str = "";
   int a = 0;
   Integer b = null;

    List listObj = new ArrayList<>();
    listObj.add("String");
    listObj.add(100);
    listObj.add(10.5);
    listObj.add(1l);
    
    if (listObj.get(0) instanceof String) {
        System.out.println("String");
        str = (String)listObj.get(0);
    }
    
    if (listObj.get(1) instanceof Integer) {
        System.out.println("Integer");
         a = (int)listObj.get(1);
         b = (Integer)listObj.get(1);
    }
    
    if (listObj.get(2) instanceof Double) {
        System.out.println("Double");
    }
    
    if (listObj.get(3) instanceof Long) {
        System.out.println("Long");
    }

如果从对象检索的值分配给变量,JVM 会要求您在编译时将其转换为特定类型。

让我们考虑:

int x = (String)listObj.get(0); 

// 在上面的例子中,从 listObj 检索到的元素是 String 并且被转换为 int。 这将解决编译时错误。但在执行时 JVM 会抛出 ClassCastException。

因此,我们可以使用 instanceof 运算符检查并将值分配给正确的变量以避免错误,而不是将值随机分配给与类型不匹配的变量。

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

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

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

您可以使用 Map 对实例进行更高的抽象

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

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

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

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

actions.get(someObject).accept(someObject)

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

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

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

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

非常简单的代码示例:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM