2016-04-10 43 views
10

如果我尝试使用错误的类的instanceof运算符我得到一个编译错误(“动物不能转换为字符串”),但与接口我没有得到编译时错误。instanceof与接口

例如:在第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"); 
     } 
    } 

} 
+0

请在问题中包含确切的错误信息。 –

+0

考虑一下:'B类扩展动物实现列表'。现在这个:'动物a =新B();' – njzk2

+0

@Tunaki你也有“Dupehammer®” - 为什么你不关闭它? (可能:你像我一样犹豫......: - /) – Marco13

回答

18

a永远不能是一个String的实例,因此编译错误。

a可以的List一个实例,如果某些子类的Animal将实现List界面,你会这样子类的实例分配给a。因此编译器允许它。

JLS

如果RelationalExpression到引用类型的铸造(§15.16)将被拒绝作为一个编译时间错误,那么的instanceof关系式同样产生一个编译时间错误。在这种情况下,表达式实例的结果永远不会是真的。

+1

是java不允许多继承是根本原因吗?同时,任何子类都可以在需要时实现接口? – nantitv

+3

@nantitv是的。由于Animal不是String的子类,Animal的任何子类都不能成为String的子类。虽然在你的特定片段中,即使允许多重继承,也不会有什么区别,因为字符串是最终的并且不能被分类。 – Eran

+0

谢谢。字符串我只是拿它作为例子。 – nantitv

1

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

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列表。