3 回答

TA貢獻(xiàn)1785條經(jīng)驗(yàn) 獲得超8個(gè)贊
以下是不可變對(duì)象的嚴(yán)格要求。
最終上課
使所有成員成為最終成員,在靜態(tài)塊或構(gòu)造函數(shù)中顯式設(shè)置它們
將所有成員設(shè)為私人
否修改狀態(tài)的方法
要特別注意限制對(duì)可變成員的訪(fǎng)問(wèn)(請(qǐng)記住,該字段可能final是可變的,但對(duì)象仍然可以是可變的。即private final Date imStillMutable)。defensive copies在這種情況下,您應(yīng)該這樣做。
上課的final原因很微妙,常常被忽略。如果不是最終的人,他們可以自由地?cái)U(kuò)展您的類(lèi),覆蓋public或protected行為,添加可變屬性,然后提供其子類(lèi)作為替代。通過(guò)聲明該類(lèi),final您可以確保不會(huì)發(fā)生這種情況。
要查看實(shí)際問(wèn)題,請(qǐng)考慮以下示例:
public class MyApp{
/**
* @param args
*/
public static void main(String[] args){
System.out.println("Hello World!");
OhNoMutable mutable = new OhNoMutable(1, 2);
ImSoImmutable immutable = mutable;
/*
* Ahhhh Prints out 3 just like I always wanted
* and I can rely on this super immutable class
* never changing. So its thread safe and perfect
*/
System.out.println(immutable.add());
/* Some sneak programmer changes a mutable field on the subclass */
mutable.field3=4;
/*
* Ahhh let me just print my immutable
* reference again because I can trust it
* so much.
*
*/
System.out.println(immutable.add());
/* Why is this buggy piece of crap printing 7 and not 3
It couldn't have changed its IMMUTABLE!!!!
*/
}
}
/* This class adheres to all the principles of
* good immutable classes. All the members are private final
* the add() method doesn't modify any state. This class is
* just a thing of beauty. Its only missing one thing
* I didn't declare the class final. Let the chaos ensue
*/
public class ImSoImmutable{
private final int field1;
private final int field2;
public ImSoImmutable(int field1, int field2){
this.field1 = field1;
this.field2 = field2;
}
public int add(){
return field1+field2;
}
}
/*
This class is the problem. The problem is the
overridden method add(). Because it uses a mutable
member it means that I can't guarantee that all instances
of ImSoImmutable are actually immutable.
*/
public class OhNoMutable extends ImSoImmutable{
public int field3 = 0;
public OhNoMutable(int field1, int field2){
super(field1, field2);
}
public int add(){
return super.add()+field3;
}
}
實(shí)際上,在依賴(lài)注入環(huán)境中遇到上述問(wèn)題是很常見(jiàn)的。您沒(méi)有顯式實(shí)例化事物,并且給出的超類(lèi)引用實(shí)際上可能是子類(lèi)。
要解決的問(wèn)題是,要堅(jiān)決保證不變性,您必須將類(lèi)標(biāo)記為final。這在Joshua Bloch的Effective Java中進(jìn)行了深入介紹,并在Java內(nèi)存模型規(guī)范中明確引用。

TA貢獻(xiàn)1757條經(jīng)驗(yàn) 獲得超8個(gè)贊
要使類(lèi)在Java中不可變,可以注意以下幾點(diǎn):
1.不要提供setter方法來(lái)修改該類(lèi)的任何實(shí)例變量的值。
2.將課程聲明為“最終”。這將防止任何其他類(lèi)對(duì)其進(jìn)行擴(kuò)展,從而阻止其覆蓋任何可能修改實(shí)例變量值的方法。
3.將實(shí)例變量聲明為private和final。
4.您還可以將類(lèi)的構(gòu)造函數(shù)聲明為私有,并在需要時(shí)添加工廠方法來(lái)創(chuàng)建類(lèi)的實(shí)例。
這些要點(diǎn)應(yīng)該有幫助?。?/p>
添加回答
舉報(bào)