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
?
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é.
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
etfinal
- 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
, ouDate
, les fairefinal
ne suffira pas. Vous devez retourner une copie défensive de leurgetters
, 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.
avec final
mot clé:
private final String name;
private final String age;
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 {
}
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.
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:
- N'utilisez aucune méthode, qui peut changer les champs de votre classe. Par exemple, n'utilisez pas de Setters.
- é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.
- déclarez la classe comme finale pour qu'elle ne puisse pas être prolongée.
- rendre tous les champs privés de sorte que l'accès direct n'est pas autorisé.
- Ne fournissent pas de setter pour les variables
- rend tous les champs modifiables définitifs de sorte que leur valeur ne puisse être attribuée qu'une seule fois.
- initialise tous les champs via un constructeur effectuant une copie profonde.
- 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.
il est trop tard pour répondre mais peut-être aider d'autres peuples qui ont cette question.
- État de l'objet immuable ne peut pas être modifié après la construction, toute modification devrait entraîner un nouvel objet immuable.
- tous les champs de la classe immuable doivent être définitifs.
- 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.
- 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
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.
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.
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
.
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
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
Faire la classe ou variable final c'est plus que suffisant
Public final class constants
{
private final String name;
private final String mobile;
// code
}