【问题标题】:instanceof throwing incompatible typesinstanceof 抛出不兼容的类型
【发布时间】:2014-12-29 05:36:52
【问题描述】:

我最近在我的以下代码 sn-p 中遇到了一个奇怪的编译错误:

class A {

}

class B extends A {

}

class Example {

}

class Demo {
    public static void main (String args[]){
        B b = new B();
        if(b instanceof Example) {
              System.out.println("Yes it is");
        }    
    }
}

现在我的谓词出现编译错误,表明 BExample 是不兼容的操作数。找了一会,发现如果没有导入右手操作数,Eclipse环境会出现这样的错误。但在我的情况下,所有类都在同一个文件中。所以我无法弄清楚这个问题。 instanceof 是否仅适用于层次结构和我一直在尝试无效的示例?

【问题讨论】:

  • B和Example之间没有继承链接,所以异常。
  • @Dev 异常在运行时抛出 - 这不是异常,这是编译错误
  • 是的,应该是编译器错误。

标签: java oop instanceof


【解决方案1】:

b被定义为B,它永远不可能是Example,因为两者之间没有继承关系。你宁愿这样做:

class Demo {
    public static void main (String args[]){
        A a = new B();
        if(a instanceof B) {
          System.out.println("Yes it is");
        }    
    }
}

或者如果你坚持使用可以包含 Example 的类型,它会是:

class Demo {
    public static void main (String args[]){
        Object o = new Example();
        if(o instanceof Example) {
          System.out.println("Yes it is");
        }    
    }
}

编译器可以并且必须检查,如果类型可以是给定的实例,请参阅JLS 15.20.2

如果将 RelationalExpression 转换为 ReferenceType 将被拒绝为 编译时错误,那么 instanceof 关系表达式同样会产生一个 编译时错误。在这种情况下,instanceof 表达式的结果 永远不可能是真的。

【讨论】:

  • 是的,我知道上面的代码应该可以工作,但是是否严格定义instanceof只能在参与的操作数在同一层次结构中时使用?
  • 是的,编译器可以而且必须静态断言。我将其添加到答案中。
【解决方案2】:

b 引用的对象绝对不可能是Example 的实例。这在编译时是已知的。

此层次结构中存在B 类型的引用

class B extends A {

}

Example

class Example {}

B 类型的变量不可能引用Example 类型的对象。例如,B 类型的实例显然已经不是Example 的子类型。此外,B 的任何子类型都将是B 的子类。由于 Java 不支持多重继承,所以它也不能是Example 的子类型。 (如果Exampleinterface,则不能这样说。)

【讨论】:

  • Sotirios 很好。当我将示例作为接口时,它不再产生错误。
  • @Sourabh 那是因为你可以创建一个B 的子类,它确实实现了Example。然后,您可以创建该类的实例并将其分配给 b
【解决方案3】:

instanceof 运算符用于运行时类型检查。例如,检查A 类型的引用是否实际上包含B 实例是有意义的。但是,ExampleB 是完全不相交的类型 - 对 B 的引用从不 包含 Example 类型的实例,因此检查它是没有意义的,并且可能在编译时失败时间。

【讨论】:

  • 好的,就是这样。我认为我的例子是错误的。我从来不知道 instanceof 只能在有两种相关类型而不是不相交类型时使用。
【解决方案4】:

instanceof 是操作员唯一的继承和实现工作。如果您要检查的对象不是来自继承层次结构,那么您将收到编译错误。这样做是下面的代码

class Demo {
    public static void main (String args[]){
        A obj = new B();
        if(obj instanceof B) {
          System.out.println("Yes it is");
        }    
    }
}

这里你不能检查 obj instanceof Example ,它的错误不是来自层次结构。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-02
    • 2021-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多