История вопроса:
Контроль уровня доступа к данным и методам в Java был введен для обеспечения инкапсуляции и защиты внутреннего устройства классов. Это важная часть ООП, позволяющая скрыть реализацию и предотвращать несанкционированное изменение состояния объектов.
Проблема:
Разные модификаторы доступа — public, protected, (package-private), private — различно ограничивают область видимости членов класса, что зачастую неочевидно. Некорректно выбранный уровень может привести к багам, нежелательному расширению прав, нарушению инкапсуляции.
Решение:
Использовать минимально необходимый модификатор доступа для каждого поля или метода. Java поддерживает:
Пример кода:
public class Dog { private String name; // видно только внутри Dog String breed; // package-private protected int age; // видно в пакете и в наследниках public void bark() { // доступно из любого кода System.out.println("Woof!"); } }
Ключевые особенности:
Может ли вложенный (inner) класс обращаться ко всем private полям внешнего класса?
Да, вложенному классу полностью доступны все поля и методы внешнего, даже private. И наоборот, внешний может обращаться к private членам вложенного класса, если имеет его экземпляр.
Может ли protected-член класса быть доступен вне пакета без наследования?
Нет. Вне пакета protected удобно только наследникам. Просто так, через объект класса в другом пакете — нельзя.
Что произойдет, если класс не объявлен public, но импортируется из другого пакета?
Класс с package-private уровнем не может быть импортирован и использован явно вне своего пакета. Попытка обратится к нему из кода другого пакета вызовет ошибку компиляции.
Негативный кейс
Все поля класса для DTO помечены public для упрощения доступа
Плюсы:
Минусы:
Позитивный кейс
Используются private поля и публичные методы доступа
Плюсы:
Минусы: