Faire un objet Java immuable

mon but est de rendre un objet Java immuable. J'ai une classe Student . Je l'ai codé de la manière suivante pour atteindre l'immutabilité:

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;
}

}

ma question Est, Quelle est la meilleure façon d'atteindre l'immuabilité pour la classe Student ?

59
demandé sur Adam Stelmaszczyk 2013-08-12 22:33:08

14 réponses

votre classe n'est pas immuable à proprement parler, elle est seulement effectivement immuable. Pour rendre immuable, vous devez utiliser final :

private final String name;
private final String age;

bien que la différence puisse sembler subtile, elle peut faire une différence significative dans un contexte multi-threadé . Une classe immuable est intrinsèquement thread-safe, une classe effectivement immuable est thread-safe seulement si elle est publiée en toute sécurité.

64
répondu assylias 2017-05-23 11:47:18

il y a peu de choses que vous devez considérer pour faire une classe immuable:

  • Faites votre classe final - vous avez déjà
  • faites toutes les zones private et final - faites les changements appropriés dans votre code
  • ne pas fournir de méthodes qui changent l'état de votre instance
  • Si vous avez des champs mutables dans votre classe, comme List , ou Date , les faire final ne suffira pas. Vous devez retourner une copie défensive de leur getters , afin que leur état ne soit pas muté par des méthodes d'appel.

pour le 4ème point, dites que vous avez un champ Date dans votre classe, alors le getter pour ce champ devrait ressembler à:

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

faire une copie défensive peut devenir un casse-tête, quand votre champ mutable lui-même comprend un certain champ mutable, et que dans turn peut contenir un autre champ mutable. Dans ce cas, vous devez faire une copie de chacun d'eux de manière itérative. Nous appelons cette copie itérative de champs mutables copie profonde .

la mise en œuvre de deep copy par vous-même peut être lourde. Mais, en gardant cette question à l'écart, vous devriez considérer votre conception de classe à nouveau, une fois que vous vous voyez tomber dans une telle exigence de faire une copie défensive profonde.

56
répondu Rohit Jain 2013-08-12 19:13:07

avec final mot clé:

private final String name;
private final String age;
3
répondu Adam Stelmaszczyk 2013-08-12 18:34:44

Prise de variables privées et pas de setter méthodes de travail pour les types de données primitifs. Si ma classe a une collection d'objets?

À toute la classe immuable à la collecte de l'objet?

écrivez votre propre objet de collection avec extension de la classe de collection et suivez les variables privées et pas de méthodes setter. ou retourner l'objet clone de votre objet de collection.

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 {

}
3
répondu 2015-04-19 04:15:37

c'est très bien mais je ferais les champs final aussi.

aussi je ferais l'âge d'un int ou double plutôt qu'une chaîne.

2
répondu Peter Lawrey 2013-08-12 18:34:53

votre exemple est déjà un objet immuable, parce que les champs de la classe Student ne peuvent être définis qu'à l'initialisation de l'instance.

pour rendre l'objet immuable, vous devez faire ces étapes:

  1. N'utilisez aucune méthode, qui peut changer les champs de votre classe. Par exemple, n'utilisez pas de Setters.
  2. éviter d'utiliser les champs publics non définitifs. Si vos champs sont publics, vous devez les déclarer définitifs et les initialiser en constructeur ou directement dans la ligne de déclaration.
2
répondu Eldar Agalarov 2013-08-12 18:43:30
  1. déclarez la classe comme finale pour qu'elle ne puisse pas être prolongée.
  2. rendre tous les champs privés de sorte que l'accès direct n'est pas autorisé.
  3. Ne fournissent pas de setter pour les variables
  4. rend tous les champs modifiables définitifs de sorte que leur valeur ne puisse être attribuée qu'une seule fois.
  5. initialise tous les champs via un constructeur effectuant une copie profonde.
  6. Effectuer le clonage d'objets dans le getter les méthodes pour retourner une copie plutôt que de retourner la référence de l'objet réel.

source

2
répondu Premraj 2017-06-22 05:47:20

il est trop tard pour répondre mais peut-être aider d'autres peuples qui ont cette question.

  1. État de l'objet immuable ne peut pas être modifié après la construction, toute modification devrait entraîner un nouvel objet immuable.
  2. tous les champs de la classe immuable doivent être définitifs.
  3. L'objet doit être correctement construit, c'est-à-dire que la référence de l'objet ne doit pas fuir pendant le processus de construction.
  4. objet être finale afin de restreindre la sous-classe pour modifier l'immutabilité de la classe mère.

je pense que ce lien Aide plus Lire la suite: http://javarevisited.blogspot.com/2013/03/how-to-create-immutable-class-object-java-example-tutorial.html#ixzz40VDQDDL1

1
répondu Yirga 2016-02-20 09:44:06

l'Élargissement de la réponse un peu.

final n'est pas la même chose que Immutable mais vous pouvez utiliser final de faire certaines choses immuables si vous utilisez une certaine façon.

certains types sont immuables, en ce qu'ils représentent des valeurs immuables plutôt que des objets à l'état changeant. Les chaînes, les nombres, etc. sont immuables. À la fin, généralement nos objets se réduisent à des structures de données éventuellement se référant à des valeurs immuables, mais nous modifiez les structures de données en attribuant de nouvelles valeurs aux mêmes noms de champ.

donc pour faire quelque chose de vraiment immuable vous devez vous assurer que final est utilisé tout le chemin vers le bas, jusqu'à ce que vous atteignez chaque champ atteignant chaque valeur à la base de votre arbre de composition. Sinon quelque chose pourrait changer sous vos l'objet et il n'est pas vraiment totalement immuable.

1
répondu Chris Travers 2017-09-20 08:09:42

c'est déjà immuable -- vous ne pouvez pas changer le contenu une fois que vous l'initialisez, puisque vous n'avez pas fait de setters. Vous pouvez ajouter des mots-clés finaux aux variables.

0
répondu Nick C 2013-08-12 18:35:23

en faisant toutes les variables comme final et en définissant un certain champ, en le faisant retourner la référence au nouvel objet Student avec la valeur nouvellement définie comme dans String .

0
répondu dev-null 2013-08-12 18:36:27

vous pouvez simplement suivre les directives indiquées dans cet exemple (premier résultat dans google): http://www.javapractices.com/topic/TopicAction.do?Id=29

0
répondu JPetric 2013-08-12 18:36:30

voici quelques règles, ce qui aide à rendre une classe immuable en Java : 1. État de l'objet immuable ne peut pas être modifié après la construction, toute modification devrait entraîner un nouvel objet immuable. 2. Tous les champs de la classe immuable doivent être définitifs. 3. L'objet doit être correctement construit, c'est-à-dire que la référence de l'objet ne doit pas fuir pendant le processus de construction. 4. L'objet doit être final afin de restreindre la sous-classe pour modifier l'immutabilité de la classe mère.

exemple:

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;
}

}

référez ce lien: http://javarevisited.blogspot.in/2013/03/how-to-create-immutable-class-object-java-example-tutorial.html

0
répondu Vijay Bhatt 2014-12-02 10:13:40

Faire la classe ou variable final c'est plus que suffisant

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

  // code
}
-1
répondu suneelkumar 2015-01-22 07:42:08