Почему мы не получаем ошибку времени компиляции для приведения здесь? - PullRequest
2 голосов
/ 11 марта 2020

В следующем примере, почему компилятор не сообщает об ошибке приведения x к D?

interface X {}
class C implements X {}
class D {}

public class CastIssue {
    public static void main(String[] args) {
        X x = new C();

        // why is there no error here?
        D d = (D) x;
    }
}

Но, если мы сделаем X классом, компилятор сообщит ошибка:

class X {}
class C extends X {}
class D {}

public class CastIssue {
    public static void main(String[] args) {
        X x = new C();

        // this gives a compile-time error
        D d = (D) x;
    }
}

1 Ответ

6 голосов
/ 11 марта 2020

Приведение от X к D разрешено, поскольку объект может быть экземпляром X и D. Например:

class E extends D implements X {}
X x = new E();
D d = (D) x; // no problem here, because an X can be a D too

В вашем примере мы можем определить из последовательности операторов, что приведение завершится неудачей , но Java не может, так как не учитывает поток управление при определении типов во время компиляции.

Однако, если X является классом, то потому что X и D не будут иметь общих подклассов (Java не разрешает множественное наследование для классов ) было бы невозможно, чтобы объект был экземпляром обоих не связанных классов. В этом случае приведение не разрешено, поскольку в зависимости от типов во время компиляции приведение никогда не будет успешным (если только x не равно null).

...