Почему модификация созданного объекта плоха в Java? - PullRequest
0 голосов
/ 25 февраля 2019

Мы все знаем, что объекты в Java могут быть изменены.

Я хочу представить три варианта при работе с объектом и указать их преимущества и недостатки.

public class SetterApplication {
    public static void main(String[] args) {
        User john = new User("John", 22);
        increaseAge(john, 2);
        System.out.println(john);       // User{name='John', age=24}

        User johnUpper = upperName(john);
        System.out.println(johnUpper);  // User{name='JOHN', age=24}
        System.out.println(john);       // User{name='JOHN', age=24}

        User johnLower = lowerName(john);
        System.out.println(johnLower);   // User{name='john', age=24}
        System.out.println(johnUpper);   // User{name='JOHN', age=24}
    }

    /**
     * Case #1
     * change the object passed in and return nothing
     * @param user user
     * @param inc inc
     */
    public static void increaseAge(User user, Integer inc) {
        user.setAge(user.getAge() + inc);
    }

    /**
     * Case #2
     * change the passed object and return the changed object
     * @param user user
     * @return User
     */
    public static User upperName(User user) {
        user.setName(user.getName().toUpperCase());
        return user;
    }

    /**
     * Case #3
     * do not change the passed object and return a completely new object
     * @param user user
     * @return User
     */
    public static User lowerName(final User user) {
        return new User(user.getName().toLowerCase(), user.getAge());
    }
}

class User {
    private String name;
    private Integer age;

    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("User{");
        sb.append("name='").append(name).append('\'');
        sb.append(", age=").append(age);
        sb.append('}');
        return sb.toString();
    }
}

"Case #1 "- наиболее распространенный способ, но для сдерживания соответствующего недостатка является то, что существующий объект модифицируетсяНо это поведение предсказуемо, поскольку мы ничего не возвращаем.

«Случай № 2» - также часто встречается в коде.Но этот случай вводит в заблуждение - потому что он возвращает измененный переданный объект, который может вводить в заблуждение, что мы возвращаем новый объект, но это не так.

«Случай № 3» - этот метод является наиболее моднымпуть.Где мы не изменяем переданный объект и возвращаем новый объект.Но в этом методе есть огромный недостаток, заключающийся в том, что в Java нелегко реализовать (глубокое) клонирование, а во-вторых, оно может быть очень ресурсоемким, объект может быть очень большим.

Мой вопроскакой из трех вариантов предпочтительнее?Что вы предпочитаете использовать?И какой из вариантов вы считаете худшим?

1 Ответ

0 голосов
/ 25 февраля 2019

Это широкая тема.В любом случае всегда предпочтительнее неизменность.
Поскольку кодирование неизменяемых классов обычно утомительно (вы можете предоставить конструктор копирования или метод копирования. А что, если я хочу скопировать только определенное подмножество его свойств?), Я используюбиблиотека Immutables .

Только не заставляйте ваш класс реализовывать Cloneable, потому что вы хотите использовать метод clone.
Избегайте этого.Вам также понадобится явное приведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...