为什么 instanceof 有时不编译,有时 returns false?
Why instanceof sometimes doesn't compile and sometimes returns false?
在下面的例子中
test instanceof java.util.Map returns false
test instanceof java.util.HashMap 不编译
但是
- mymap instanceof 设置 returns false
和
- mymap instanceof HashSet returns false(为什么编译成功?!?)
为什么?他们长得很像!
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);
}
}
instanceof 运算符在 Java 中用于测试引用是否指向某个对象,该对象是特定 class 或接口的实例。
例如:
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 总是 returns false:
System.out.println(null instanceof Object); // false, null doesn't reference any object
有时编译器肯定知道引用永远不可能是特定 class 的实例,因为引用的类型不在特定 class 的层次结构树中。
例如,在以下示例中,编译器会报错:
"不兼容的条件操作数类型 String 和 Map"
String myString="test string";
System.out.println(myString instanceof java.util.Map);
现在,事情变得有趣了。在下面的示例中,我们有一个 non final class Test 和一个 final class 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. 中 return false,但在 2., 3., 4. 中不编译?
在 1. 中,我们正在针对 Interface (java.util.Map) 进行参考测试。编译器无法确定 test 不是 java.util.Map 的实例。事实上,测试可能会引用一个对象,该对象的 class 实现了 java.util.Map 并扩展了 class 测试。因此,没有编译错误,但在运行时 returns false。
在 2. 中,我们正在针对 Class 进行参考测试。在这种情况下,编译器可以确定 test 变量引用的对象不能扩展 java.util.Map,因为 Test class 不会扩展 java.util.Map,并且每个 subclass of Test 将扩展 class 测试(或其子 class 之一),因此它不能同时扩展 java.util.Map。
在 3. 中,我们正在针对 Interface 测试参考 testFinal。它看起来与 1. 类似,但它有很大不同,因为 class TestFinal 不能被 subclassed,所以 TestFinal 的实例不可能也是 java.util.Map 的实例.
在 4. 中,我们正在针对 Class 测试参考 testFinal。和2.一样,编译器可以确定testFinal变量引用的对象不能extend 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是对Interface的引用,理论上可以存在一个实现了Map或者扩展了HashMap的List实例。
类似于1.
类似于2.
结论:
一个。 null instanceof AnyClass(或AnyInterface) 总是 returns false
乙。 myreferenceToAClass instanceof MyInterface 可能 return 真或假,取决于上下文
C。 myreferenceToAnInterface instanceof AnyClass(或AnyInterface) 可能 return 真或假,取决于上下文
D. myreferenceToAClass instanceof MyClass:
- 如果 myreference 的 class 不属于 MyClass 的层次结构树,则会出现编译错误
- 如果 myreference 的 class 属于 MyClass 的层次结构树
,returns true 或 false,取决于上下文
在下面的例子中
test instanceof java.util.Map returns false
test instanceof java.util.HashMap 不编译
但是
- mymap instanceof 设置 returns false 和
- mymap instanceof HashSet returns false(为什么编译成功?!?)
为什么?他们长得很像!
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);
}
}
instanceof 运算符在 Java 中用于测试引用是否指向某个对象,该对象是特定 class 或接口的实例。
例如:
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 总是 returns false:
System.out.println(null instanceof Object); // false, null doesn't reference any object
有时编译器肯定知道引用永远不可能是特定 class 的实例,因为引用的类型不在特定 class 的层次结构树中。 例如,在以下示例中,编译器会报错: "不兼容的条件操作数类型 String 和 Map"
String myString="test string";
System.out.println(myString instanceof java.util.Map);
现在,事情变得有趣了。在下面的示例中,我们有一个 non final class Test 和一个 final class 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. 中 return false,但在 2., 3., 4. 中不编译?
在 1. 中,我们正在针对 Interface (java.util.Map) 进行参考测试。编译器无法确定 test 不是 java.util.Map 的实例。事实上,测试可能会引用一个对象,该对象的 class 实现了 java.util.Map 并扩展了 class 测试。因此,没有编译错误,但在运行时 returns false。
在 2. 中,我们正在针对 Class 进行参考测试。在这种情况下,编译器可以确定 test 变量引用的对象不能扩展 java.util.Map,因为 Test class 不会扩展 java.util.Map,并且每个 subclass of Test 将扩展 class 测试(或其子 class 之一),因此它不能同时扩展 java.util.Map。
在 3. 中,我们正在针对 Interface 测试参考 testFinal。它看起来与 1. 类似,但它有很大不同,因为 class TestFinal 不能被 subclassed,所以 TestFinal 的实例不可能也是 java.util.Map 的实例.
在 4. 中,我们正在针对 Class 测试参考 testFinal。和2.一样,编译器可以确定testFinal变量引用的对象不能extend 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是对Interface的引用,理论上可以存在一个实现了Map或者扩展了HashMap的List实例。
类似于1.
类似于2.
结论:
一个。 null instanceof AnyClass(或AnyInterface) 总是 returns false
乙。 myreferenceToAClass instanceof MyInterface 可能 return 真或假,取决于上下文
C。 myreferenceToAnInterface instanceof AnyClass(或AnyInterface) 可能 return 真或假,取决于上下文
D. myreferenceToAClass instanceof MyClass: - 如果 myreference 的 class 不属于 MyClass 的层次结构树,则会出现编译错误 - 如果 myreference 的 class 属于 MyClass 的层次结构树
,returns true 或 false,取决于上下文