Я нашел странное ограничение компиляции, которое я не могу объяснить, и я не понимаю эту причину ограничения.
Пример-1:
Рассмотрим эти классы:
В package e1;
:
public class C1 {
enum E1 { A, B, C }
public E1 x;
}
В package e2;
:
import e1.C1;
public class C2 {
public String test(C1 c1) {
return c1.x.toString(); // here compilation error
}
}
Это приводит к следующей ошибке компиляции:
Ошибка: (5,20) java:
toString()
вjava.lang.Enum
определяется в недоступном классе или интерфейсе
Пример-2:
Рассмотрим эти классы:
В package i1;
:
public interface I1 {
int someMethod();
}
public class C1 {
static class I2 implements I1 {
public int someMethod() {
return 1;
}
}
public I2 x = new I2();
}
В package i2;
:
import i1.C1;
import i1.I1;
public class C2 {
public static void main(String[] args) {
C1 c1 = new C1();
System.out.println(c1.x.someMethod()); // compilation error
}
}
Это также вызывает ту же ошибку компиляции, но если мы изменим строку нарушения на:
System.out.println(((I1)c1.x).someMethod());
Тогда это может быть скомпилировано и отлично работает.
Итак, вопрос:
Почему это ограничение доступности необходимо?
Да, я понимаю, что классы C1.E
в примере-1) и C1.I2
в примере-2) являются закрытыми для пакета. Но в то же время ясно, что никто не может назначить более слабый доступ привилегии к методам базового интерфейса (I1
of Object
), поэтому всегда будет безопасно делать прямое литье объекта в его базовый интерфейс и получать доступ к ограниченному методу.
Может ли кто-нибудь объяснить цели и причину этого ограничения?
UPDATE: assylias указал JLS §6.6 +0,1:
Элемент (класс, интерфейс, поле или метод) ссылочного типа (класса, интерфейса или массива) или конструктор типа класса доступен только в том случае, если тип доступен...
Похоже, это ограничение, но оно не объясняет почему это ограничение (в случае вышеупомянутых примеров) необходимо...