JavaRush /Java блог /Архив info.javarush /Геттеры и нарушенная инкапсуляция
Vadelic
14 уровень
Пасадена

Геттеры и нарушенная инкапсуляция

Статья из группы Архив info.javarush
Решая задачи, я столкнулся с неожиданным поведением геттеров. В здешних лекциях и даже в генерируемых IntelliJ IDEA геттерах используется простейшая схема: public final class A { private A field; public A getField() { return field; } public void setField(A field) { this.field = field; } } Если поле примитивного типа или String, которые передаются по значению, то всё в порядке, но если объект передаётся по ссылке, то получается, что через геттер можно получить полный доступ к полю, что сводит на нет установленный уровень доступа protected. Если в сеттере стоит какое-либо условие валидности, то через такой геттер его можно обойти, что нарушает инкапсуляцию и правильно было бы создавать клон объекта, что бы избежать этой неприятности. Понимаю, что не все объекты просто клонировать и если это отдаётся на ответственность программиста, то странно почему об этом нигде в лекциях не встречалось упоминаний. UPD: Геттер, как идея, конечно же, не нарушает инкапсуляцию, но написан он должен быть так, что бы не предать принципов ООП. Это значит, что если геттер выдаёт объект, то таким образом, что бы пользователь не смог его изменить никаким другим способом, который прописан в классе. В классе Collections существует замечательный метод public static Collection unmodifiableCollection(Collection c) который выдаёт read-only коллекцию. Это накладывает ряд других ограничений, например, невозможность сортировки, но на этот случай в этом классе есть: unmodifiableSortedSet unmodifiableSortedMap и ещё несколько, для большего удобства.
Комментарии (35)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
yag0andy Уровень 41
21 января 2016
Не совсем понял, в чем нарушается инкапсуляция?
Вы получаете геттером ссылку на экземпляр класса А. Класс А тоже имеет внутреннюю структуру, разные модификаторы доступа… Скажем, доступа к приватным полям класса А вы не получаете через геттер. Все норм… Геттер просто возвращает ссылку на значение в поле А… Что не так? В чем противоречие?

Если бы всё было в А скрыто — то какой толк в такой ссылке? Как с ней работать?
Fry Уровень 41
21 января 2016
Открою тебе маленький секрет, даже к приватным полям можно получить доступ, и поменять значение, без геттеров и сеттеров, и даже можно поменять адрес в памяти.