Подтвердить что ты не робот

Сделать неизменным объект Java

Моя цель - сделать объект Java неизменным. У меня есть класс Student. Я закодировал его следующим образом, чтобы достичь неизменности:

public final class Student {

private String name;
private String age;

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

public String getName() {
    return name;
}

public String getAge() {
    return age;
}

}

Мой вопрос: какой лучший способ достичь неизменности для класса Student?

4b9b3361

Ответ 1

Ваш класс не является неизменным, строго говоря, он только эффективен. Чтобы сделать его неизменным, вам нужно использовать final:

private final String name;
private final String age;

Хотя разница может казаться тонкой, она может существенно повлиять на многопоточный контекст. Неизменяемый класс по сути является потокобезопасным, эффективно неизменяемый класс является потокобезопасным, только если он безопасно опубликован.

Ответ 2

Есть несколько вещей, которые вы должны учитывать для создания неизменяемого класса:

  • Сделайте свой класс final - у вас уже есть
  • Сделать все поля private и final - внести соответствующие изменения в свой код
  • Не указывайте какие-либо методы, которые изменяют состояние вашего экземпляра
  • Если у вас есть изменяемые поля в вашем классе, например List или Date, сделать их final не хватит. Вы должны вернуть защитную копию из своих getters, чтобы их состояние не было мутировано с помощью методов вызова.

Для 4-го пункта, скажем, у вас есть поле Date в вашем классе, тогда получатель для этого поля должен выглядеть так:

public Date getDate() {
    return new Date(this.date.getTime());
}

Создание защитной копии может стать головной болью, когда ваше изменяемое поле включает в себя некоторое изменяемое поле и, в свою очередь, может содержать какое-то другое изменяемое поле. В этом случае вам нужно будет сделать копию каждого из них итеративно. Мы называем эту итеративную копию изменяемых полей как Deep Copy.

Реализация глубокой копии самостоятельно может быть громоздкой. Но, сохраняя эту проблему отдельно, вы должны снова рассмотреть свой классный дизайн, как только увидите, что вы попадаете в такое требование сделать глубокую защитную копию.

Ответ 3

  • Объявить класс окончательным, чтобы он не расширялся.
  • Сделать все поля закрытыми, чтобы прямой доступ не разрешался.
  • Не предоставлять методы настройки для переменных
  • Сделать все изменяемые поля окончательными, чтобы его значение можно было назначить только один раз.
  • Инициализировать все поля через конструктор, выполняющий глубокую копию.
  • Выполнение клонирования объектов в методах getter для возврата копии, а не возврата фактической ссылки на объект.

источник

Ответ 4

С ключевым словом final:

private final String name;
private final String age;

Ответ 5

Использование переменных private и no setter методов будет работать для примитивных типов данных. Если у моего класса есть коллекция объектов?

Как сделать любой класс неизменным с объектом коллекции?

Напишите свой собственный объект коллекции с расширением класса коллекции и следуйте за частными переменными и без методов настройки. или вернуть клон объекта вашего объекта коллекции.

public final class Student {

private StudentList names;//Which is extended from arraylist

public Student() {
names = DAO.getNamesList()//Which will return All Student names from Database  its upto you how you want to implement.
}

public StudentList getStudentList(){
return names;//you need to implement your own methods in StudentList class to iterate your arraylist; or you can return Enumeration object.
}

public Enumeration getStudentNamesIterator(
Enumeration e = Collections.enumeration(names);
return e;
}

public class StudentList extends ArrayList {

}

Ответ 6

Это хорошо, но я бы сделал поля final.

Также я сделал бы возраст an int или double, а не String.

Ответ 7

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

Чтобы сделать объект неизменным, вы должны сделать следующие шаги:

  • Не используйте какие-либо методы, которые могут изменять поля вашего класса. Например, не используйте Setters.
  • Избегайте использования общедоступных нефинализированных полей. Если ваши поля являются общедоступными, вы должны объявить их окончательными и инициализировать их в конструкторе или непосредственно в строке объявления.

Ответ 8

Немного разложим ответ.

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

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

Итак, чтобы сделать что-то действительно неизменное, вам нужно убедиться, что финал используется до конца, пока вы не достигнете каждого поля, достигающего каждого значения в базе вашего дерева композиций. В противном случае что-то может измениться из-под вашего объекта, и оно не является полностью неизменным.

Ответ 9

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

  • Состояние неизменяемого объекта не может быть изменено после построения, любая модификация должна привести к появлению нового неизменяемого объекта.
  • Все поля класса Immutable должны быть окончательными.
  • Объект должен быть правильно сконструирован, т.е. ссылка на объект не должна протекать во время процесса сборки.
  • Объект должен быть окончательным, чтобы ограничить подкласс для изменения неизменяемости родительского класса.

Я думаю, эта ссылка поможет больше Подробнее: http://javarevisited.blogspot.com/2013/03/how-to-create-immutable-class-object-java-example-tutorial.html#ixzz40VDQDDL1

Ответ 10

Он уже неизменен - ​​вы не можете изменить содержимое после его инициализации, поскольку вы не создали сеттеры. Вы можете добавить конечные ключевые слова к переменным.

Ответ 11

Создание всех переменных в качестве final и при установке некоторого поля, чтобы вернуть ссылку на новый объект Student с новым значением, как в String.

Ответ 13

Вот несколько правил, которые помогают сделать класс неизменным в Java: 1. Состояние неизменяемого объекта не может быть изменено после постройки, любая модификация должна привести к появлению нового неизменяемого объекта. 2. Все поля класса Immutable должны быть окончательными. 3. Объект должен быть правильно сконструирован, т.е. Ссылка на объект не должна течь во время процесса строительства. 4. Объект должен быть окончательным, чтобы ограничить подкласс для изменения неизменяемости родительского класса.

Пример:

public final class Contacts {

private final String name;
private final String mobile;

public Contacts(String name, String mobile) {
    this.name = name;
    this.mobile = mobile;
}

public String getName(){
    return name;
}

public String getMobile(){
    return mobile;
}

}

Перейдите по этой ссылке: http://javarevisited.blogspot.in/2013/03/how-to-create-immutable-class-object-java-example-tutorial.html

Ответ 14

Согласно Стратегии определения неизменяемых объектов

  1. Не предоставляйте " setter " методы - методы, которые изменяют поля или объекты, на которые ссылаются поля.

  2. Сделайте все поля final и private.

  3. Не позволяйте подклассам переопределять методы. Самый простой способ сделать это - объявить класс как final.

    а. Более сложный подход - сделать constructor частным и создать экземпляры в фабричных методах.

  4. Если поля экземпляра содержат ссылки на изменяемые объекты, не допускайте изменения этих объектов:

    а. Не предоставляйте методы, которые изменяют изменяемые объекты.

    б. Не делитесь ссылками на изменяемые объекты. Никогда не храните ссылки на внешние изменяемые объекты, переданные в конструктор; при необходимости создайте копии и сохраните ссылки на копии. Аналогичным образом, при необходимости создайте копии ваших внутренних изменяемых объектов, чтобы избежать возврата оригиналов в ваши методы.

Ответ 15

Сделайте класс или переменную окончательной, что более чем достаточно

Public final class constants
{
  private final String name;
  private final String mobile;

  // code
}