Как работают геттеры и сеттеры java
Геттеры и сеттеры защищают значение переменной от неожиданных изменений. Когда переменная скрыта модификатором private и доступна только через геттер и сеттер, она инкапсулирована(скрыта от прямого доступа). Поэтому реализация геттеров и сеттеров является одним из способов обеспечения инкапсуляции в коде программы.
Например создадим класс User:
public class User private int id; private String name; // возможно тут будет конструктор. // получаем значение поля id public int getId() return id; > // записываем значение в поле id public void setId(int id) this.id = id; > // получаем значение поля name public String getName() return name; > // записываем значение в поле name public void setName(String name) this.name = name; > >
Создадим экземпляр класса User и применим к нему геттеры и сетторы:
User user = new User(); //Зададим значение полей через сеттеры user.setId(1); user.setName("Mark"); //Получим значения полей через геттеры String name = user.getName(); int id = user.getId();
Зачем нужны геттеры и сеттеры java

Как вы заметили, 2-й элемент массива scores изменяется вне сеттера (в строке 5). Поскольку геттер возвращает ссылку на scores, внешний код, имея эту ссылку, может вносить изменения в массив.
Решение этой проблемы заключается в том, что геттеру необходимо возвращать копию объекта, а не ссылку на оригинал. Модифицируем вышеупомянутый геттер следующим образом:
public int[] getScores()
То же самое для copyOf:
public int[] getScores()
Поэтому правило таково: не возвращайте ссылку на исходный объект в геттере. Возвращайте копию.
5. Реализация геттеров и сеттеров для примитивных типов
Переменные примитивных типов вы можете свободно передавать/возвращать прямо в сеттере/геттере, потому что Java автоматически копирует их значения. Таким образом, ошибок № 2 и № 3 можно избежать.
Например, следующий код безопасен, потому что сеттер и геттер работают с примитивным типом float:
private float amount; public void setAmount(float amount) < this.amount = amount; >public float getAmount()
Таким образом, примитивные типы не наделены проблемами объектов.
6. Реализация геттеров и сеттеров для объектов системных классов
Геттеры и сеттеры для String
String — это immutable-тип. Это означает, что после создания объекта этого типа, его значение нельзя изменить. Любые изменения будут приводить к созданию нового объекта String. Таким образом, как и для примитивных типов, вы можете безопасно реализовать геттер и сеттер для переменной String:
private String address; public void setAddress(String address) < this.address = address; >public String getAddress()
Геттеры и сеттеры для объектов типа Date
Т.к. объекты класса java.util.Date являются изменяемыми, то внешние классы не должны иметь доступ к их оригиналам. Данный класс реализует метод clone() из класса Object, который возвращает копию объекта, но использовать его для этих целей не стоит.
По этому поводу Джошуа Блох пишет следующее: «Поскольку Date не является окончательным классом, нет гарантии, что метод clone() возвратит объект, класс которого именно java.util.Date: он может вернуть экземпляр ненадежного подкласса, созданного специально для нанесения ущерба. Такой подкласс может, например, записывать ссылку на каждый экземпляр в момент создания последнего в закрытый статический список, а затем предоставить злоумышленнику доступ к этому списку. В результате злоумышленник получит полный контроль над всеми экземплярами копий. Чтобы предотвратить атаки такого рода, не используйте метод clone() для создания копии параметра, тип которого позволяет ненадежным сторонам создавать подклассы».
Для чего используются геттеры и сеттеры в Java?
Добрый день! Подскажите, пожалуйста, новичку, для чего используются сеттеры и геттеры в Java?
Суть я понимаю, что они позволяют получать доступ к переменным других классов с уровнем доступа private, но зачем тогда ставить уровень доступа private на переменные, если все равно через геттеры и сеттеры можно их считать из другого класса.
P.S. Сильно не ругайте, только начал осваивать Java.
- Вопрос задан более трёх лет назад
- 711 просмотров
1 комментарий
Простой 1 комментарий
Сергей Горностаев @sergey-gornostaev Куратор тега Java
Сильно не ругайте, только начал осваивать Java.
Читайте учебник дальше, там должно быть объяснение.
Решения вопроса 0
Ответы на вопрос 7
Dmitry Roo @xez Куратор тега Java
TL Junior Roo
Вопрос, кстати, очень даже не глупый.
Вы абсолютно правильно заметили насчет нарушения инкапсуляции гетерами и сеттерами, но никто же не заставляет вас их писать. Если вы считаете, что объет должен быть иммутабельным — устанавливаете все поля final и инициализируете их только через конструктор. Насчет геттеров — тоже, в зависимости от бизнес-логики, не всегда они нужны.
По этой теме почитайте литературу про ООП (например «Объектно ориентированный подход» Вайсфельда).
И еще, например, Егор Бугаенко по этой теме имеет мнение (относиться к нему стоит со здоровым скептицизмом).
https://www.youtube.com/watch?v=lfdAwl3-X_c&t
Ответ написан более трёх лет назад
Нравится 4 4 комментария

С Егором аккуратно нужно новичку подкидывать. по сути ответа согласен и докинул ниже свой ответ
Dmitry Roo @xez Куратор тега Java
Максим Федоров, я и говорю: «со здоровым скептицизмом».
Денис Загаевский @zagayevskiy Куратор тега Java
Dmitry Roo, Кто такой этот Егор и почему его мнение важно?
Dmitry Roo @xez Куратор тега Java
Денис Загаевский, ну так по ссылке можно перейти и там все понятно будет.

maksfedorov.ru
Нет никакого смысла, если нормально программировать и строить простой удобный код. Этакий способ формально соблюсти инкапсуляцию и сокрытие данных: состояние приватное? Приватное 🙂
Чреваты тем, что плодят высокую связанность в коде, состояние и управляется снаружи (на основе геттеров) и контролируются инварианты где угодно и как угодно. По сути превращаем сущности в структуры, но тк это все же бизнес-объекты, а знания бизнес-состояния нужно — то они гуляют по всему проекту и ничем не ограничены. заплетая и заплетая код снова и снова, а также погружая в эти «сущности» все больше и больше знаний.
Доходит до того, что через заказ можно достать товар, через товар можно достать поставщика, через поставщика пользователя с данными аутентификации. и все работает со всем. плодя кучу сервисов и взрывая мозг.
Нужны только бля быстрых CRUD и для совместимости с кучей библиотек. А также говнокодерам «использовать данные в сервисах»
Сеттеры и геттеры нужны для разных манипуляций: валидация, костыльного маппинга, сериализации и десерриализации.
Хорошими и современной практикой сейчас является — не использование и геттеров и сеттеров.
Мои изыскания:
Зачем (не)нужны геттеры?
Геттеры/сеттеры и проблема с инкапсуляцией (примеры на Symfony, аналог Spring в php с аналогичной плохой практикой)
Что такое геттеры и сеттеры в программировании
Это будет текст об архитектуре объектно-ориентированных программ. Это для тех, кто планирует серьёзно заниматься разработкой.
В объектно-ориентированном программировании многое основано на объектах — специальных «коробках» из данных и функций, которые работают в программе как единое целое. Внутри объекты могут быть устроены сложно, но снаружи из них торчат понятные «ручки» и «индикаторы» — то, через что другие части программы с этими объектами взаимодействуют.
Например, можно представить, что автомобиль — это объект: у него внутри много сложных деталей и связей между ними. Но снаружи всё относительно просто: руль, педали, переключатели, фары, спидометр, тахометр, индикатор температуры, уровня топлива и т. д. Чтобы этим управлять, нам не нужно знать внутреннее устройство машины, а достаточно изучить основные внешние функции.

Одно из понятий ООП — инкапсуляция, и в нём часто применяется такая идея:
доступ к внутренним данным объекта нельзя получить напрямую — это делается через специальные механизмы. Это нужно для того, чтобы другие части программы не могли нештатным образом повлиять на работу объекта.
Если говорить про автомобиль, то внутренние данные объекта — это объём бензина в миллилитрах, который поступает в двигатель на каждом такте работы. Водитель не может управлять этим напрямую и лить в двигатель сколько угодно бензина. Вместо этого он может нажать на педаль газа, а машина дальше сама рассчитает концентрацию бензина в воздушно-топливной смеси.
Такие механизмы доступа к данным через посредника называются геттеры и сеттеры.
Что такое геттер и сеттер
Эти слова пришли из английского от слов get (получать) и set (устанавливать).
Задача геттера — получить данные о чём-то внутри объекта и передать их наружу. Например, водитель не может постоянно заглядывать в бензобак и смотреть, сколько бензина. Вместо этого водитель смотрит на индикатор топлива — тот показывает, сколько бензина осталось в баке. Индикатор топлива — это геттер: он берёт данные из объекта (автомобиль) и отдаёт их тому, кто их попросил (водитель).
Сеттер работает иначе: он меняет значения внутри объекта. В примере с автомобилем педаль газа — это сеттер: в зависимости от силы нажатия она изменяет объём впрыска топлива в двигатель. Так производители защищают двигатель от нештатных ситуаций: даже при нажатии педали газа в пол в двигатель попадёт безопасное количество топлива.
Геттеры и сеттеры в программировании
Чаще всего в программировании эти инструменты используются как метод или интерфейс объекта: вы создаёте объект и указываете, что с ним можно делать. Поясним на примере.
Допустим, мы делаем голосовалку для интернет-магазина — люди выбирают, нравится им какой-то товар или нет. Одна из наших задач — сделать так, чтобы в коде программы ничто не могло напрямую влиять на значение счётчика. Всё, что мы разрешаем, — это увеличить счётчик на единицу или узнать текущее значение. Это избавит нас от ситуации, когда какая-то функция вдруг захочет накрутить счётчик сразу на 10 тысяч голосов. Чтобы так сделать, нам достаточно спрятать переменную счётчика в объект и там же объявить два метода — чтения (узнать результат) и записи (проголосовать, то есть увеличить строго на единицу). Для этого даже необязательно создавать отдельный класс. В JavaScript, например, это можно сделать за счёт стандартного замыкания, когда мы вкладываем одну функцию в другую.
// Объявляем новый объект-константу с помощью стрелочной функции const createCounter = () => < // Доступ к этой переменной возможен только внутри этой функции, снаружи поменять её не получится let count = 0; // Что возвращает функция return (< // Если вызван метод upvote(), увеличиваем переменную счётчика на 1 upvote: () =>count += 1, // Если вызван метод getVoteCount, возвращаем значение счётчика getVoteCount: () => count.toLocaleString() >); >; // Создаём новый объект на основе своего const counter = createCounter(); // Кликаем пару раз, увеличивая счётчик на единицу // Другим способом мы не сможем его изменить counter.upvote(); counter.upvote(); // Смотрим, что получилось в итоге (2) console.log(counter.getVoteCount());
А если в основной программе попробовать поменять значение переменной count, то ничего не изменится. А всё потому, что доступ к переменной count возможен только изнутри объекта и только двумя разрешёнными способами.
// ❌ Кажется, что это тоже сработает, но на самом деле значение счётчика не изменится
counter.count = 100
// На выходе всё так же будет число 2
console.log(counter.getCount());

Зачем они нужны
Основная задача геттеров и сеттеров — защитить данные внутри объекта, чтобы они менялись по своим правилам, а не кто как захочет. Проще говоря, это посредники, которые смотрят, можно что-то сделать с данными или нет. Если можно — делают, если нельзя — нет. В итоге и данные в безопасности, и у пользователя есть инструмент для работы с ними.
Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.