Модификаторы доступа
Модификатор доступа определяет, откуда код может обратиться к типу или члену. Это compile-time граница API, а не полноценная защита секретов.
| Модификатор члена | Тот же класс | Тот же пакет | Наследник в другом пакете | Любой код |
|---|---|---|---|---|
private | да | нет | нет | нет |
| package-private | да | да | нет | нет |
protected | да | да | да* | нет |
public | да | да | да | да |
* В другом пакете protected доступен наследнику через механизм наследования. Нельзя произвольно обратиться к защищённому члену любого экземпляра родительского типа.
package child;
class Child extends parent.Parent {
void update(Child other) {
this.protectedValue = 1;
other.protectedValue = 2;
// new Parent().protectedValue = 3; // недоступно
}
}Отсутствие ключевого слова означает package-private. Top-level класс или интерфейс бывает только public либо package-private. Вложенный member type допускает все четыре уровня.
Не-access модификаторы
static, final, abstract, synchronized, native, transient, volatile, strictfp, sealed, non-sealed меняют другие свойства. Они не являются уровнями видимости и применимы не ко всем объявлениям.
Как выбирать
Начинать с минимальной видимости, достаточной контракту:
private— деталь реализации;- package-private — сотрудничество внутри пакета и package-level тест;
protected— осознанная точка расширения;public— поддерживаемый внешний API.
Модули Java добавляют ещё одну границу: public тип из неэкспортированного пакета недоступен обычному коду другого модуля.
Ошибки
- делать поле
publicвместо метода, защищающего инвариант; - использовать
protectedкак «доступно везде рядом»; - раскрывать изменяемую коллекцию публичным getter;
- путать доступность reflection с обычными правилами языка и модулей.
На собеседовании
Как называется доступ без модификатора? Package-private.
Может ли top-level класс быть private? Нет.
Чем protected отличается от package-private? Добавляет доступ наследнику из другого пакета, но с ограничением формы доступа.
Гарантирует ли private безопасность данных? Нет, это граница кода, а не криптографическая защита.
Связано: Инкапсуляция, Пакеты Java, Понятие рефлективность Java.