Объем частного конструктора в вложенном классе
Это скорее головоломка, чем вопрос. У меня есть следующий код:
public class PrivateBaseConstructor {
public static class BaseClass {
private BaseClass() {
}
}
public static class DerivedClass extends BaseClass {
public DerivedClass() {
super(); // 1*
}
}
}
Здесь вызов super();
в 1 * является допустимым событием, хотя конструктор базового класса private
. Если мы будем писать классы как отдельные классы в одном пакете:
BClass.java
public class BClass {
private BClass() {
}
}
DClass.java
public class DClass extends BClass {
public DClass() {
super(); // 2*
}
Компилятор правильно дает ошибку при 2 *, поскольку конструктор базового класса не отображается.
Почему компилятор не выдает ошибку в моем первом сценарии, когда оба класса объявляются статическими в пределах одного класса?
Ответы
Ответ 1
если член или конструктор объявлен приватным, тогда доступ разрешен тогда и только тогда, когда он встречается внутри тела класса верхнего уровня (§7.6), который включает объявление члена или конструктора.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6.1
Ответ 2
Так как вложенные классы могут видеть друг друга. Это не имеет никакого отношения к статическим объявлениям. См. Следующий пример кода с только вложенными внутренними классами (не статическими).
public class PrivateBaseConstructor {
public class BaseClass {
private BaseClass() {}
}
public class DerivedClass extends BaseClass {
public DerivedClass() {
super(); // 1*
}
}
public static void main(String[] args)
{
new PrivateBaseConstructor(). new DerivedClass();
}
}
Подробнее о вложенных классах читайте здесь: http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
Ответ 3
Поскольку все, что объявлено внутри класса, может обращаться к его закрытым членам, включая внутренние классы. Однако, если вы запустите PMD в своем классе, вы обнаружите, что это говорит о том, что вы меняете видимость конструктора на не-private.