Instanceof с интерфейсом

Если я пытаюсь использовать оператор 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");
        }
    }

}

Ответ 1

a никогда не может быть экземпляром String, поэтому ошибка компиляции.

a может быть экземпляром List, если какой-либо подкласс класса Animal будет реализовывать интерфейс List, и вы должны назначить экземпляр такого подкласса a. Поэтому компилятор позволяет это.

Из JLS:

Если листинг (§15.16) RelationalExpression для ReferenceType будет отклонен как ошибка времени компиляции, то экземпляр реляционного выражения также производит ошибку времени компиляции. В такой ситуации результат выражения instanceof никогда не может быть правдой.

Ответ 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.