+-
java – 为什么instanceof有时不编译,有时返回false?
参见英文答案 > The ‘instanceof’ operator behaves differently for interfaces and classes                                    2个
在以下示例中

> test instanceof java.util.Map返回false
> test instanceof java.util.HashMap无法编译

> mymap instanceof Set返回false

> mymap instanceof HashSet返回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);
    }
}
最佳答案
在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);

现在,事情变得有趣了.在下面的示例中,我们有一个非最终类Test和一个最终类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.中,我们正在测试针对类的参考测试.在这种情况下,编译器可以确定测试变量引用的对象不能扩展java.util.Map,因为Test类不扩展java.util.Map,并且Test的每个子类都将扩展类Test(或它的一个子类),所以它不能同时扩展java.util.Map.

在3.中,我们正在针对接口测试参考testFinal.它看起来与1.类似,但它完全不同,因为类TestFinal不能被子类化,所以TestFinal的实例也无法成为java.util.Map的实例.

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

结论:

A. null instanceof AnyClass(或AnyInterface)总是返回false

B. myreferenceToAClass instanceof MyInterface可能会返回true或false,具体取决于上下文

C. myreferenceToAnInterface instanceof AnyClass(或AnyInterface)可能返回true或false,具体取决于上下文

D. myreferenceToAClass的MyClass实例:
   – 如果myreference的类不属于MyClass的层次结构树,则编译错误
   – 如果myreference的类属于MyClass的层次结构树,则返回true或false,具体取决于上下文

点击查看更多相关文章

转载注明原文:java – 为什么instanceof有时不编译,有时返回false? - 乐贴网