Оператор instanceof в java с интерфейсами

Может ли кто-нибудь объяснить следующее поведение в Java с помощью оператора instanceof.

Runnable r = new Thread();

даже несмотря на то, что тип переменной r является Runnable, и сравнение instanceof выполняется для классов, которые не находятся в одной и той же иерархии классов.

System.out.println(r instanceof String); // This line does not compile 

System.out.println(r instanceof Vector); // This line compiles

System.out.println(r instanceof FileNotFoundException); // This line compiles

person redeemed    schedule 10.08.2017    source источник


Ответы (3)


String класс равен final -- это означает, что он не может быть подклассом. Более того, он не реализует Runnable. Все это известно во время компиляции; следовательно, ошибка компиляции.

person Maurice Perry    schedule 10.08.2017
comment
Более конкретно: String не реализует Runnable, и у него не может быть подклассов, которые реализуют (потому что это final). - person T.J. Crowder; 10.08.2017
comment
@T.J.Crowder Да, +1, было бы неплохо отредактировать ответ, чтобы сделать его более полезным. - person Erwin Bolwidt; 10.08.2017
comment
@ErwinBolwidt: Да. Я оставлял это Морису. Но все равно это обман, так что... - person T.J. Crowder; 10.08.2017

Пример:

static class First {

}

static final class Second {

}

И тогда :

    Runnable r = new Thread();

    System.out.println(r instanceof First);

    System.out.println(r instanceof Second);

Компилятор видит, что Second это final, поэтому он не может иметь никаких sub-classes, поэтому он не может реализовать Runnable.

person Eugene    schedule 10.08.2017

Класс String — это класс final, и он не реализует интерфейс Runnable. Следовательно, r instanceof String никогда не может возвращать true (поскольку не может быть никакого подкласса String, который реализовывал бы Runnable), поэтому компилятор этого не допускает.

С другой стороны, могут быть подклассы класса Vector или класса FileNotFoundException, которые реализуют интерфейс Runnable, поэтому r instanceof Vector и r instanceof FileNotFoundException могут возвращать true, насколько это может сказать компилятор.

Это описано в JLS 15.20. .2:

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

person Eran    schedule 10.08.2017