Зачем нужны геттеры и сеттеры java
Перейти к содержимому

Зачем нужны геттеры и сеттеры java

  • автор:

Как работают геттеры и сеттеры 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 комментария

Maksclub

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

Maksclub

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());

Что такое геттеры и сеттеры в программировании

Зачем они нужны

Основная задача геттеров и сеттеров — защитить данные внутри объекта, чтобы они менялись по своим правилам, а не кто как захочет. Проще говоря, это посредники, которые смотрят, можно что-то сделать с данными или нет. Если можно — делают, если нельзя — нет. В итоге и данные в безопасности, и у пользователя есть инструмент для работы с ними.

Получите ИТ-профессию

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *