Свойство неизменности в Java - PullRequest
1 голос
/ 21 марта 2012

Я знаю, что когда дело доходит до передачи объектов в Java, ссылка на объект передается как значение.То, что вы когда-либо вносите в этот объект, отражается и в исходном объекте.Чтобы избежать этого, мы используем свойство неизменяемости в java.

Итак, мой вопрос, я создал неизменный класс Employee, когда я передаю объект этого Employee классадля какого-либо метода в другом классе, я не хочу, чтобы этот метод вносил какие-либо изменения в этот объект.Даже если это произойдет, я не хочу, чтобы изменения влияли на исходный объект, созданный в вызывающем классе.

Вот мой пример кода.

public final class Employee {
    int employeeId;

    public int getId() {
        return employeeId;
    }

    public void setId(int id) {
        this.employeeId = id;
    }

}

public class Worker {
    public static void process(Employee f, Employee g){
        int c = f.getId();
        f.setId(g.getId());
        g.setId(c);
    }
}

public class ImmutabilityTest{

    public static void main(String[] args) {
        Employee teamMember = new Employee();
        Employee teamLead = new Employee();
        teamMember.setId(5);
        teamLead.setId(10);
        System.out.println("Before process "+teamMember.getId() + " " + teamLead.getId());
        Worker.process(teamMember, teamLead);
        System.out.println("After process "+teamMember.getId() + " " + teamLead.getId());
    }
}

Вывод будет

Before process 5 10
After process 10 5

Есть ли способ избежать изменения значений переменных-членовСотрудник класса?(кроме создания их final) Если нет, то как мы на самом деле используем свойство Неизменность в Java в пользовательском классе?

Любые предложения / мнения / указатели приветствуются!Спасибо ..

Ответы [ 5 ]

5 голосов
/ 21 марта 2012

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

Вот (более) неизменяемая версия вашего класса Employee:

public class Employee {
    final int employeeId;

    public Employee(final int id) {
        super();
        this.employeeId = id;
    }

    public int getId() {
        return employeeId;
    }
}

Обратите внимание, что отражение в Java делает практически невозможным достижение истинной неизменности, даже с использованием переменных конечного экземпляра и клонирования.

4 голосов
/ 21 марта 2012

Employee имеет установщик , а имеет не приватное поле, поэтому оно не неизменяемое .

Удалить установщики сделайте поле private, и ваша проблема будет решена.

Другой вариант - передать копию объекта (обычно с помощью конструктор копирования создать его)

1 голос
/ 21 марта 2012

Применение ключевого слова final к классу просто означает, что класс не может быть расширен (или подклассифицирован).

Это не имеет никакого отношения к тому, могут ли быть изменены его члены.

1 голос
/ 21 марта 2012

Вы можете изменить видимость метода setId на частный пакет и убедиться, что Worker находится в пакете, отличном от Employee.

Либо полностью удалите метод setId.

[Если другой класс вносит изменения] Я не хочу, чтобы на изменения влиял исходный объект, созданный в вызывающем классе.

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


Обратите внимание, что если вы не объявите приватное поле employeeId равным final, вы не получите полного преимущества неизменности. Строго говоря, метод getId необходимо синхронизировать, если есть вероятность, что разные потоки вызовут getId в одном и том же экземпляре Employee.

0 голосов
/ 21 марта 2012

Если вы не хотите, чтобы кто-то изменил значение ваших свойств, вы можете сохранить их как приватные без установщика.

...