Мы все знаем, что если мы специально не определяем конструктор, компилятор вставляет невидимый конструктор нулевого параметра. Я думал, что его модификатор доступа был общедоступным, но, столкнувшись с проблемой внутреннего класса, я обнаружил, что я ошибся. Вот мой код:
public class Outer {
protected class ProtectedInner {
// adding a public constructor will solve the error in SubOuterInAnotherPackage class
//public ProtectedInner() {}
}
}
И в другом пакете есть подкласс Outer
:
public class SubOuterInAnotherPackage extends Outer {
public static void main(String[] args) {
SubOuterInAnotherPackage.ProtectedInner protectedInner
= new SubOuterInAnotherPackage().new ProtectedInner(); // Error!! Can't access the default constructor
}
}
Вы получите сообщение об ошибке в методе main()
, но если вы добавите публичный конструктор в класс ProtectedInner
, эта ошибка будет решена. Поэтому я думаю, что модификатор конструктора по умолчанию не является общедоступным! Так может ли кто-нибудь сказать мне, что такое модификатор доступа конструктора по умолчанию?
Ответ 1
Я думал, что его модификатор доступа является общедоступным, но когда я сталкиваюсь с проблемой внутреннего класса, я обнаружил, что, возможно, ошибся.
Угу. Действительно, я оказался в той же ситуации пару лет назад. Я был удивлен ошибкой (через инъекцию Guice, что сделало ее немного сложнее найти).
Ключ должен проверить спецификацию, в данном случае раздел 8.8.9:
В классе типа, если класс объявлен открытым, то конструктор по умолчанию неявно получает общедоступный модификатор доступа (§6.6); если класс объявлен защищенным, то конструктор по умолчанию неявно получает защитный код доступа (§6.6); если класс объявлен приватным, то конструктор по умолчанию неявно получает доступный модификатор доступа (§6.6); в противном случае конструктор по умолчанию имеет доступ по умолчанию, подразумеваемый модификатором доступа.
Итак, в этом случае ваш конструктор неявно protected
.
Ответ 2
В дополнение к тому, что Джон довольно хорошо заявил, вот пример изображения для визуальных парней.
Если в классе нет конструктора, компилятор автоматически создает конструктор по умолчанию.
Вот пример, который успешно отображает приведенное выше правило:
![введите описание изображения здесь]()
Для получения дополнительной информации см. здесь.
Ответ 3
Я хотел бы отметить еще одну вещь, которую я недавно получил.
Если вы определяете конструктор по умолчанию для своего класса, то спецификатором acess будет то, что вы назначили. Например,
public class A{
A(){
// do some stuff
}
}
Здесь спецификатором доступа конструктора по умолчанию является доступ к пакету, а не общедоступный доступ (класс).
Однако
public class A{
// no constructor is defined
}
Здесь компилятор будет сочувствовать вам и предоставить вам конструктор по умолчанию, спецификатор доступа которого будет таким же, как и общедоступный класс.