【问题标题】:instanceof with an interface [duplicate]带有接口的instanceof [重复]
【发布时间】:2016-07-31 11:07:47
【问题描述】:

如果我尝试对错误的类使用 instanceof 运算符,则会收到编译错误(“Animal 无法转换为 String”),但使用接口时我不会收到编译时错误。

例如:在第 10 行,我收到一个编译错误,因为 Animal 不是 String 的子类。但是在第 14 行,即使 Animal 没有实现 List 接口,我也没有收到编译错误。

class Animal {

}

public class InstanceOf {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
         Animal a = new Animal();
        if (a instanceof String ){  //line 10
            System.out.println("True");
        }

         if (a instanceof List ){ //line 14
            System.out.println("True");
        }
    }

}

【问题讨论】:

  • 请在问题中包含确切的错误信息。
  • 考虑一下:class B extends Animal implements List。现在这个:Animal a = new B();
  • @Tunaki 你也有“Dupehammer®”——你为什么不关闭它? (可能:你和我一样犹豫不决......:-/)
  • @Marco13 不,昨天只是没有投票:)

标签: java instanceof


【解决方案1】:

a 永远不能是 instanceof String,因此会出现编译错误。

a 可以是List 的实例,如果Animal 的某个子类将实现List 接口,并且您可以将此类子类的实例分配给a。因此编译器允许这样做。

来自JLS

如果将 RelationalExpression 转换为 ReferenceType(第 15.16 节)作为编译时错误被拒绝,则 instanceof 关系表达式同样会产生编译时错误。在这种情况下,instanceof 表达式的结果永远不会为真。

【讨论】:

  • java不允许多重继承是根本原因吗?同时任何子类都可以随时实现接口?
  • @nantitv 是的。由于 Animal 不是 String 的子类,因此 Animal 的任何子类都不能是 String 的子类。尽管在您的特定 sn-p 中,即使允许多重继承也不会产生影响,因为 String 是最终的并且不能被子类化。
  • 谢谢。字符串我只是举个例子。
  • @nantitv 如果你告诉编译器不会有Animal 的子类,它实际上可以推断instanceof 毫无意义:只需将class Animal{} 替换为final class Animal{} .
【解决方案2】:

我只是根据这个问题做了一个实验。

class Animal {}
interface AnimalA {}
class AnimalB{} 

class AnimalC extends Animal,AnimalB {} //not possible
class AnimalD extends Animal implements AnimalA{} //possible   

public class InstanceOfTest {

    public static void main(String[] args) {
        Animal a = new Animal();
        if(a instanceof AnimalA) { //no compile time error
            System.out.println("interface test");
        }
        if(a instanceof AnimalB) { //compile time error
            System.out.println("interface test");
        }
        if(a instanceof List) { //compile time error
            System.out.println("interface test");
        }
        if(a instanceof ArrayList) { //compile time error
            System.out.println("interface test");
        }
    }
}

正如@Eran 所说,Animal 不是AnimalB 的子类,它的子类不能成为AnimalB 的实例。但另一方面,它的任何子类都可以实现interface List。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-23
    • 1970-01-01
    • 1970-01-01
    • 2017-09-11
    • 1970-01-01
    • 2014-10-17
    • 2012-07-24
    相关资源
    最近更新 更多