Comment pouvons-nous maintenir l'Immuabilité d'une classe avec une référence mutable
Je connais toutes les règles de base pour rendre notre classe immuable, mais je suis un peu confus quand il y a une autre catégorie de référence. Je sais que si il y a de collecte au lieu de Address
alors nous pouvons faire usage de Collections.unmodifiableList(new ArrayList<>(modifiable));
et puis nous pouvons faire de notre classe immuable. Mais en dessous de cas, je suis toujours incapable d'obtenir le concept.
public final class Employee{
private final int id;
private Address address;
public Employee(int id, Address address)
{
this.id = id;
this.address=address;
}
public int getId(){
return id;
}
public Address getAddress(){
return address;
}
}
public class Address{
private String street;
public String getStreet(){
return street;
}
public void setStreet(String street){
this.street = street;
}
}
Employee
n'est pas immuable, et il n'y a pas beaucoup que vous pouvez faire pour changer cela si vous ne pouvez pas changer le Address
classe pour prendre en charge au minimum de la copie, mais de préférence en Address
immuable dans la première place.
OriginalL'auteur user1111880 | 2015-12-05
Vous devez vous connecter pour publier un commentaire.
Bien, le concept est la lecture de la JLS et de la compréhension. Dans ce cas, le JLS dit:
Si vous avez besoin de:
address
final et privé.Dans ce cas, #2 signifie probablement que vous ne pouvez pas retourner une référence à l'Adresse que vous avez avec
getAddress()
. Et vous devez faire une copie défensive dans le constructeur. I. e., faire une copie de tout mutable paramètre, et de stocker la copie de l'Employé. Si vous ne pouvez pas faire une copie défensive, il n'y a vraiment aucun moyen de faire de l'Employé immuable.La mise en œuvre de
clone()
ou quelque chose de similaire (une copie ctor) rendrait la création de la défensive des objets plus facile pour compliqué les classes. Cependant, la meilleure recommandation que je pense serait de faireAddress
immuable. Une fois que vous faites cela, vous pouvez passer librement autour de sa référence sans fil-les questions de sécurité.Dans cet exemple, je ne PAS ont pour copier la valeur de
street
.Street
est une Chaîne de caractères, et les chaînes sont immuables. Sistreet
se composait de champs mutables (entier le numéro de la rue par exemple), alors je serait devez faire une copie destreet
aussi, et ainsi de suite ad infinitum. C'est pourquoi des objets immuables, sont si précieux, ils cassent la "infini" copie de la chaîne.grande marque , j'ai un peu le concept, mais comme nous l'avons déjà créé l'Adresse de l'objet de l'Employé () constructeur alors pourquoi nous mettons en place à nouveau dans getAdress() la méthode
J'ai dit pourquoi, au moins deux fois. JL dit l'Employé de l'objet n'est pas immuable, sauf si nous prévenir interne références d'être vu. Si nous utilisons la valeur qui a été transmise dans le ctor, alors n'importe qui pourrait être la tenue de cette référence. On ne peut donc pas l'utiliser, nous devons faire notre propre objet que personne d'autre ne peut voir.
Dans getAddress() la méthode il y a une erreur: il doit être présent.adresse.getStreet()
Droit, merci pour cette remarque.
OriginalL'auteur markspace
Eh bien, il est des mesures fournies par Java docs
Classe d'adresse est mutable parce que vous pouvez le modifier avec l'setStreet méthode.
De sorte que les autres classe peut modifier cette classe.
Nous pouvons nous défendre contre ce en prenant une copie de l'instance de l'Adresse quand il est passé, plutôt que de faire confiance à la référence à l'exemple nous est donné.
Faisant l'Adresse de l'objet final
Deuxièmement,
Créer constructeur dans la classe d'Adresse qui définit la Rue.Supprimer la méthode de définition de rue.
Et, enfin, au lieu de
Utilisation
J'ai mis à jour la réponse... Consulter javaranch.com/journal/2003/04/immutable.htm aussi,
S'il vous plaît marquer la solution ACCEPTÉE si votre problème est résolu.De cette façon, il va aider les autres à la recherche pour le même problème
OriginalL'auteur Naruto
Si vous voulez encapsuler un mutable objet dans un immuable, alors vous avez besoin de:
ne jamais stocker la référence à l'origine mutable objet.
publique Employé(int id, Adresse){
OriginalL'auteur Neeraj Gahlawat
Donc dans votre exemple
Employee
classe est immuable, parce qu'une fois qu'il est créé, vous ne pouvez pas changer d'état, car il ne possède que des méthodes de lecture.Address
classe estmutable
parce que vous pouvez le modifier avec l'setStreet
méthode.Donc, si vous avez d'autres classe qui utilise
Address
objet, vous êtes sûr que cette classe ne peut pas modifier les objets de l'état.OriginalL'auteur jonasnas
Vous pouvez également utiliser la copie superficielle à l'aide de clonage
À l'aide de cette volonté de créer un objet distinct de l'Adresse des Employés de la classe dans ce cas, toutes les modifications apportées à l'Adresse de l'objet passé en argument de l'Employé constructeur ne va pas changer la variable de membre de l'Adresse de l'objet de la classe Employé.
La getAddress() la méthode est également de retour en un clone de l'objet afin que toutes les modifications apportées à l'objet récupéré par cette méthode n'affecte pas l'adresse d'un objet de la classe Employé.
Remarque:
Pour utiliser cette Adresse de classe Clonable.
OriginalL'auteur sanjeev51