‘instanceof’ 运算符在 Java 中用于什么?

instanceof操作符是用来做什么的? 我见过这样的东西

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

但我一点都不明白。我已经做了调查,但只找到了一些没有任何解释的例子。

250079 次浏览

如果 source是一个 object变量,那么 instanceof就是一种检查它是否是 Button的方法。

它是一个操作符,如果表达式的左边是 实例,右边是类名,则返回 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

希望这个能帮上忙!

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

想象一下:

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的子类型,也不是 Cat的超类型,而且它也没有实现它。

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

注意: 对于所有类型 TexpressionThatIsNull instanceof T都是 false。

非常简单的代码示例:

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

小心点。在上面的例子中,如果 Class1是 Object,那么第一个比较将始终为 true。因此,就像例外一样,等级秩序很重要!

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

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

正如在其他答案中提到的,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英镑,第114页)。例如,以下内容将无法编译:

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

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


}
}

实例的更高抽象

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)

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

假设您抛出异常,当您有 catch 时,执行 sum 自定义操作,然后按照逻辑继续(抛出或日志等)

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

2)现在进入捕捉模块 Catch (例外情况 e){ 如果异常类型为“ InvalidExtensionsException”,则执行和逻辑

InvalidExtensionsException InvalidException =(InvalidExtensionsException)e;

3)如果你不检查实例和异常类型是空指针异常,你的代码会中断。

所以您的逻辑应该位于 如果(e instanceof InvalidExtensionsException){ 例外 = (InvalidExtensionsException) e; }

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

可以作为相等检查的速记。

所以这个代码

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

可以写成

if(ob instanceOf ClassA) {
}
 

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。

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

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

这里有一个简单的例子:

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

最好的解释是 JLS。 总是尝试检查来源说什么。在那里你会得到最好的答案加上更多。 在这里复制一些部分:

Instanceof 的关系表达式操作数的类型 运算符必须是引用类型或空类型; 否则,为 发生编译时错误。

方法之后提到的 ReferenceType 是否为编译时错误 Instanceof 运算符不表示可重新指定的引用类型 (4.7).

如果关系表达式对 ReferenceType 的强制转换(15.16) 将被作为编译时错误拒绝,然后是 instanceof 关系表达式同样会产生编译时错误 情况下,instanceof 表达式的结果永远不可能是 没错。

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

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

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

模式基本上是测试一个值是否具有特定的类型,并且当它具有匹配的类型时,可以从值中提取信息。 模式匹配可以更清晰有效地表达系统中的公共逻辑,即有条件地从对象中删除组件。

在 Java14之前

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

Java14增强

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

当运行时对象(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 运算符检查并将值分配给正确的变量,以避免错误,而不是随机地将值分配给与类型不匹配的变量。