@xzoyart

Как правильно возвращать значение из геттера?

Проходя тему геттеров и сеттеров оставался один вопрос: Необходимо ли каждый раз возвращать клонированный объект из геттра? Я знаю что примитивные типы данных автоматически клонируются, но что делать с объектами, особенно если там большая вложенность?

Например, есть какой-то объект, мы его возвращаем без клонирования (то есть возвращаем ссылку), далее в коде изменяем его и выводим на экран, при этом изменяется и сам объект в классе, что недопустимо.

Какие варианты вижу я:
  1. С помощью SerializationUtils.clone() делать глубокое клонирование и возвращать объект, далее, если его нужно будет изменить в самом классе, делаю это с помощью сеттера. Вижу только одну проблему, если будет что-то тяжёлое, то глубокое клонирование сильно замедлит программу.
  2. Отдать ссылку и если это необходимо клонировать объект уже в коде.


Когда отдавать ссылку, а когда глубокую копию объекта?

public class Game {
        Player player = new Player();
        Field gameField = player.getField();
        // Изменили объект в самом классе, так как отдали ссылку
        Field newField = SomeClass.change(gameField); 
        System.out.println(newField); 
}

public class Player {
    private Field field;

    public Field getField() {
        return this.field;
    }
}
  • Вопрос задан
  • 1322 просмотра
Решения вопроса 3
AshBlade
@AshBlade
Просто хочу быть счастливым
Полностью зависит от контекста. Здесь нет правильного ответа.
Можно выделить 2 случая:
1. Код полностью твой
2. Код будут использовать другие пользователи

Если случай 1, то делай как хочешь. Здесь ты главный и знаешь что менять можно, а что нет
Если случай 2, то тут уже зависит:
- Если возвращаешь объект, который может (и должен) быть изменен - делай изменяемым
- Если это слепок состояния - то можно подумать над неизменяемым состоянием
- Можно прописать это (то что нельзя изменять объект) в документации к методу геттера

Дополнительно, если тебе так уж нужна неизменяемость, то добавляй интерфейсы. Возвращай какой-нибудь интерфейс с одними геттерами.
Ответ написан
Комментировать
@Dmtm
Android
геттер всегда возвращает ссылку на один и тот же объект, это просто способ доступа к членам класса
(иначе если в коде два вызова геттера - будет создано два новых объекта?),
если геттер создает новый объект - это не геттер и его лучше оформить отдельным методом
в яве даже Cloneable интерфейс ввели чтобы подчеркнуть особый случай
PS: стоит посмотреть на паттерны Prototype и Factory
Ответ написан
Комментировать
mayton2019
@mayton2019 Куратор тега Java
Bigdata Engineer
Желательно возвращать либо иммутабельные объекты (LocalDateTime вместо java.util.Date)
либо клонировать.

Если вернуть сложный объект со связями, то дальнейшее использование этого может
привести к сложным и трудно-воспроизводимым багам.

Разумеется жизнь полна исключений и тут главное чтоб вся команда разработчиков ПОНИМАЛА что
ты сделал и для чего. Иначе будут конфликты и война правок в коде проекта.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы