在以下示例中
test.of java.util.Map返回false
java.util.HashMap的测试实例不编译
但
为什么呢?它们看起来非常相似!
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
public class InstanceofTest {
public static class Test {}
public static void main(String[] args) {
// -- left operand references a Class instance
Test test = null;
// 1. outputs: false
System.out.println(test instanceof Map);
// 2. COMPILATION ERROR
System.out.println(test instanceof HashMap);
// -- left operand references an Interface instance
Map mymap = new HashMap();
// 3. outputs: false
System.out.println(mymap instanceof Set);
// 4. outputs: false
System.out.println(mymap instanceof HashSet);
}
}
答案 0 :(得分:6)
在Java中使用instanceof运算符来测试引用是否指向作为特定类或接口的实例的对象。
例如:
String myString="test string";
System.out.println(myString instanceof String); // true, myString is a String
System.out.println(myString instanceof Object); // true, myString is a String, and so it is an Object, too
对于 null 引用, instanceof 始终返回 false :
System.out.println(null instanceof Object); // false, null doesn't reference any object
有时编译器确定引用永远不能是特定类的实例,因为引用的类型不在特定类的层次结构树中。 例如,在以下示例中,编译器会抱怨: " 不兼容的条件操作数类型字符串和地图 "
String myString="test string";
System.out.println(myString instanceof java.util.Map);
现在,事情变得有趣了。在以下示例中,我们有一个非最终类测试和一个最终类TestFinal 。
public class InstanceofTest {
public static class Test {}
public static final class TestFinal {}
public static void main(String[] args) {
Test test = null;
// 1. outputs: false
System.out.println(test instanceof java.util.Map);
// 2. COMPILATION ERROR
System.out.println(test instanceof java.util.HashMap);
TestFinal testFinal = null;
// 3. COMPILATION ERROR
System.out.println(testFinal instanceof java.util.Map);
// 4. COMPILATION ERROR
System.out.println(testFinal instanceof java.util.HashMap);
}
}
为什么它在1.中返回false,但它不会在2.,3.,4中编译。?
在1.中,我们正在针对接口(java.util.Map)测试参考测试。编译器无法确定测试不是java.util.Map的实例。实际上,测试可能会引用一个对象,该对象的类实现了java.util.Map并扩展了类Test。因此,没有编译错误,但它在运行时返回false。
在2.,我们正在针对 Class 测试参考测试。在这种情况下,编译器可以确定测试变量引用的对象不能扩展java.util.Map,因为Test类不会扩展java.util.Map,并且Test的每个子类都会扩展类Test (或其子类之一),因此它不能同时扩展java.util.Map。
在3.中,我们正在针对接口测试参考testFinal。它看起来与1.类似,但它完全不同,因为类TestFinal不能被子类化,所以TestFinal的实例也不可能是java.util.Map的实例。 / p>
在4.,我们正在针对 Class 测试参考testFinal。与2.一样,编译器可以确保testFinal变量引用的对象不能扩展java.util.Map。
还有另一个案例值得考虑:
List myList = new ArrayList();
// 5. outputs: false
System.out.println(myList instanceof java.util.Map);
// 6. outputs: false
System.out.println(myList instanceof java.util.HashMap);
ArrayList myArrayList = new ArrayList();
// 7. outputs: false
System.out.println(myArrayList instanceof java.util.Map);
// 8. COMPILATION ERROR
System.out.println(myArrayList instanceof java.util.HashMap);
在5.,6中,myList是对接口的引用,理论上它可以存在一个实现Map或扩展HashMap的List实例。
类似于1.
类似于2.
结论:
一个。 null instanceof AnyClass (或 AnyInterface )始终返回false
B中。 myreferenceToAClass instanceof MyInterface 可能会返回true或false,具体取决于上下文
℃。 myreferenceToAnInterface instanceof AnyClass (或 AnyInterface )可能会返回true或false,具体取决于上下文
d。 myreferenceToAClass instanceof MyClass : - 如果myreference的类不属于MyClass的层次结构树,则编译错误 - 如果myreference的类属于MyClass的层次结构树,则返回true或false,具体取决于上下文