Mon objectif est de rendre un objet Java immuable. J'ai une classe Student
. Je l'ai codé de la manière suivante pour obtenir 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 la suivante: quel est le meilleur moyen d’atteindre l’immuabilité de la classe Student
?
Votre classe n'est pas immuable à proprement parler, elle n'est qu'immuable. Pour le 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 uniquement si elle est publiée en toute sécurité.
Il y a peu de choses que vous devez considérer pour faire une classe immuable:
final
- Vous avez déjàprivate
et final
- Apportez les modifications appropriées dans votre codeList
ou Date
, les rendre final
ne suffira pas. Vous devriez renvoyer une copie défensive à partir de leur getters
, afin que leur état ne soit pas muté par les méthodes appelantes.Pour le 4ème point, supposons que vous ayez un champ Date
dans votre classe, alors le getter pour ce champ devrait ressembler à ceci:
public Date getDate() {
return new Date(this.date.getTime());
}
Faire une copie défensive peut devenir un casse-tête lorsque votre champ mutable comprend lui-même un champ mutable, et que celui-ci peut contenir un autre champ mutable. Dans ce cas, vous devrez faire une copie de chacun d'eux de manière itérative. Nous nommons cette copie itérative de champs mutables comme Deep Copy .
La mise en œuvre de la copie en profondeur par vous-même peut s'avérer fastidieuse. Mais, en gardant cette question à part, vous devriez revoir votre conception de classe, une fois que vous vous retrouvez dans l’obligation de faire une copie défensive en profondeur.
Avec le mot clé final
:
private final String name;
private final String age;
Rendre les variables privées et aucune méthode de définition fonctionnera pour les types de données primitifs. Si ma classe a une collection d'objets?
Rendre toute classe immuable avec objet de collection?
Ecrivez votre propre objet de collection avec une classe de collecte et suivez les variables privées sans méthode de définition ou retourne un objet clone de votre objet 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 {
}
C’est bien, mais je ferais aussi les champs final
.
De plus, je ferais de l’âge une variable int
ou double
plutôt qu’une chaîne.
Développer un peu la réponse.
final
n'est pas la même chose que Immutable
mais vous pouvez utiliser final
pour rendre certaines choses immuables si vous l'utilisez de certaines manières.
Certains types sont immuables, en ce sens qu'ils représentent des valeurs immuables plutôt que des objets d'état changeant. Les chaînes, les nombres, etc. sont immuables. À la fin, nos objets se limitent généralement à des structures de données, référençant éventuellement des valeurs immuables, mais nous les modifions en affectant de nouvelles valeurs aux mêmes noms de champs.
Donc, pour rendre quelque chose de vraiment immuable, vous devez vous assurer que la version finale est utilisée jusqu'au bout, jusqu'à atteindre chaque champ atteignant chaque valeur à la base de votre arbre de composition. Sinon, quelque chose pourrait changer de dessous votre objet et ce n'est pas vraiment totalement immuable.
Votre exemple est déjà un objet immuable, car les champs de la classe Student ne peuvent être définis que lors de l'initialisation d'instance.
Pour rendre un objet immuable, vous devez suivre ces étapes:
Il est trop tard pour répondre, mais cela pourrait peut-être aider d'autres peuples qui ont cette question.
Je pense que ce lien aide davantage Lisez plus: http://javarevisited.blogspot.com/2013/03/how-to-create-immutable-class-object-Java-example-tutorial.html#ixzz40VDQDDL1
C'est déjà immuable - vous ne pouvez pas changer le contenu une fois que vous l'avez initialisé, car vous n'avez pas encore créé de paramètres. Vous pouvez ajouter des mots clés finaux aux variables.
Définir toutes les variables en tant que final
et lors de la définition d'un champ, le rendre ainsi renvoyer la référence au nouvel objet Student
avec la nouvelle valeur définie, comme dans String
.
Vous pouvez simplement suivre les directives présentées dans cet exemple (premier résultat dans Google): http://www.javapractices.com/topic/TopicAction.do?Id=29
Voici quelques règles permettant de rendre une classe immuable en Java: 1. L'état de l'objet immuable ne peut pas être modifié après la construction, toute modification doit aboutir à un nouvel objet immuable . 2. Tous les champs de la classe Immutable 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 parente.
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-vous à ce lien: http://javarevisited.blogspot.in/2013/03/how-to-create-immutable-class-object-Java-example-tutorial.html
Selon Stratégie de définition des objets immuables
Ne fournissez pas de méthodes "setter
" - des méthodes qui modifient des champs ou des objets référencés par des champs.
Définissez tous les champs final
et private
.
N'autorisez pas les sous-classes à remplacer les méthodes. Le moyen le plus simple consiste à déclarer la classe en tant que final
.
a. Une approche plus sophistiquée consiste à rendre la constructor
privée et à construire des instances dans les méthodes d'usine.
Si les champs d'instance incluent des références à des objets mutables, n'autorisez pas ces objets à être modifiés:
a. Ne fournissez pas de méthodes qui modifient les objets mutables.
b. Ne partagez pas les références aux objets mutables. Ne stockez jamais de références à des objets externes, mutables, transmis au constructeur; si nécessaire, créez des copies et stockez les références aux copies. De même, créez des copies de vos objets mutables internes si nécessaire pour éviter de renvoyer les originaux dans vos méthodes.