[英]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
因为Animal
是Dog
的超类型,可能不太“精致”。
和,
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.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);
}
}
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
因为它将实例与类型进行比较。 它返回true
或false
。 如果我们将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.