Ошибка в компиляторе затмения или Javac? - PullRequest
7 голосов
/ 16 апреля 2009

Кто прав? Затмение или Джавац?

--------------- c / v / A.java ---------------

package c.v;
public class A<T> {
}

--------------- c / v / B.java ---------------

package c.v;
public class B extends A<B.Secret> {
  private class Secret {};
}

Eclipse прекрасно компилирует B.java.

У Javac есть проблема.

$ javac c/v/B.java
c/v/B.java:3: c.v.B.Secret has private access in c.v.B
public class B extends A<B.Secret> {
                           ^
    1 error

Ответы [ 3 ]

7 голосов
/ 16 апреля 2009

Соответствующие части Спецификации языка Java должны быть:

§8.1.4: [...] ClassType должен назвать доступный (§6.6) тип класса, иначе произойдет ошибка времени компиляции.

§6.6.1: [...] Элемент (класс, интерфейс, поле или метод) ссылочного типа (класс, интерфейс или массив) или конструктор типа класса доступен только в том случае, если тип доступен, а элемент или конструктор объявлен для разрешения доступа:

  • Если член или конструктор объявлен как открытый, то доступ разрешен. Все члены интерфейсов неявно общедоступны. [...]
    • В противном случае, если член или конструктор объявлен закрытым, тогда доступ разрешается тогда и только тогда, когда он происходит в теле класса верхнего уровня (§7.6), в котором содержится объявление члена или конструктора.

Так как ClassType не находится в теле класса, B.Secret недоступен в этом месте, поэтому A<B.Secret> недоступен, поэтому должна произойти ошибка времени компиляции.

6 голосов
/ 16 апреля 2009

Затмение не так. Если вы рекламируете что-то как

extends A<X>

Вам нужно знать об A и X.

3 голосов
/ 16 апреля 2009

Я склонен думать, что Джавак прав. Для того, чтобы создать новый класс

A<B.Secret>

универсальный должен иметь доступ к классу, который он использует. Тот факт, что B затем расширяет этот класс, является второстепенным.

...