2016-04-10 14 views
10

Se provo a utilizzare l'operatore instanceof con classe errata, sto ricevendo un errore di compilazione ("Animal non può essere convertito in String") ma con un'interfaccia non ricevo l'errore del tempo di compilazione.instanceof con un'interfaccia

Ad esempio: Nella riga 10 viene visualizzato un errore di compilazione perché Animal non è una sottoclasse di String. Ma nella riga 14 non sto ottenendo un errore di compilazione anche se Animal non implementa l'interfaccia 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

Si prega di includere l'esatto messaggio di errore nella domanda. –

+0

Considera questo: 'la classe B estende l'elenco degli attrezzi animali'. Ora questo: 'Animal a = new B();' – njzk2

+0

@Tunaki Hai anche il "Dupehammer®" - perché non l'hai chiuso? (Probabilmente: sei esitante quanto me ...: - /) – Marco13

risposta

18

a non può mai essere un'istanza di stringa, quindi l'errore di compilazione.

a può essere un'istanza di List se qualche sottoclasse di Animal sarebbe implementare l'interfaccia List e si dovrebbe assegnare un'istanza di tale sottoclasse di a. Pertanto il compilatore lo consente.

Dal JLS:

Se un cast (§15.16) del RelationalExpression al ReferenceType verrebbe rifiutato come errore di compilazione, allora l'espressione relazionale instanceof produce anche un errore di compilazione. In una situazione del genere, il risultato dell'istanza di espressione non potrebbe mai essere vero.

+1

java non è permesso ereditarietà multipla è la causa principale? Allo stesso tempo, qualsiasi sottoclasse può implementare un'interfaccia ogni volta che lo desidera? – nantitv

+3

@nantitv Sì. Poiché Animal non è una sottoclasse di String, qualsiasi sottoclasse di Animal non può essere una sottoclasse di String. Anche se nel tuo frammento specifico, non farebbe differenza anche se fosse consentita l'ereditarietà multipla, poiché String è definitivo e non può essere sottoclassato. – Eran

+0

Grazie. String Ho appena preso per un esempio. – nantitv

1

Solo un esperimento che ho fatto da questa domanda.

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"); 
     } 
    } 
} 

Quindi, come ha detto @Eran, come Animal non è una sottoclasse di AnimalB non della sua sottoclasse può diventare e l'istanza di AnimalB. Ma dall'altra parte della sua sottoclasse può implementare l'elenco interface.