如何創建對常量對象的引用?如何在Java中創建一個常量對象?
final Myclass obj = new Myclass();
不起作用,它表示obj(引用)不應該被重新賦值,但我們仍然可以更改引用的對象。
我想確保對象本身一旦構建就不會改變。
如何創建對常量對象的引用?如何在Java中創建一個常量對象?
final Myclass obj = new Myclass();
不起作用,它表示obj(引用)不應該被重新賦值,但我們仍然可以更改引用的對象。
我想確保對象本身一旦構建就不會改變。
只是使它不可變(如String
是)。或者將其包裝在另一個對象中,該對象限制訪問有問題的對象的增變器(如Collections.unmodifiableList()
和consorts)。
檢查有效Java中的「有利於不變性」:http://wiki.glassfish.java.net/attach/JavaProgramming/ej.html#immutablerecipe – dfa 2010-01-27 13:47:50
@dfa:這太棒了。但是,他的第二本書有討論的鏈接嗎? – 2011-06-01 16:50:55
是的,你似乎忘記了設置類型。
final MyClass obj = new Myclass();
這意味着obj只能分配一次。 Java沒有像C++那樣的const關鍵字。如果MyClass沒有被聲明爲final(final class MyClass {...}),它仍然可以改變。
最終變量應在聲明時分配。
final MyClass obj = new MyClass();
我不認爲有任何內置的關鍵字做到這一點在Java中。即使參考是恆定/最終的,對象的內部仍然可以改變。
你最好的選擇是擁有你的類的ReadOnly實現版本。
你可以閱讀更多關於此這裏:http://en.wikipedia.org/wiki/Const-correctness#final_in_Java
你需要的是一個Immutable Object。 Java中沒有可以立即使對象不可變的關鍵字。你必須設計對象的邏輯,以便它的狀態不能改變。正如BalusC所說的那樣,你可以把它包裝在另一個對象中,這個對象限制對它的增變器的訪問。
在Java對象常量意味着你不能改變它的引用,但你可以改變它的狀態變量的值,直到它們不是最終的。如果所有的成員變量都是最終的,那麼它就是一個完美的常量,你不能改變任何東西。
你在混合兩件事:final和immutable。
變量可以是最終,所以不能改變它的值(或對象引用)被初始化之後(但當然也可以改變參考的對象屬性)
對象可以是不可變的(不是關鍵字,而是屬性),因此在創建後您無法將其更改爲值。字符串是一個很好的例子 - 你不能在String對象內改變後備char []。
嗨。我有一個問題問你。當你說'最後'時,'你在初始化後不能改變它的值(或對象引用)「,我明白這一點。所以'final int x = 10; x = 11;'會產生編譯器錯誤。但我不明白你的第二個陳述'但當然你可以改變引用的對象屬性'。你能提供一小段代碼給我看嗎?我將不勝感激。 tyvm – 2011-06-01 16:47:25
@Harry Pham - 聽起來很複雜,但不是:考慮一個'final List l = new ArrayList()'。您不能將另一個列表指定給'l'(因爲它是最終的),但可以將對象添加到列表中。這是*改變列表屬性*:在這個例子中包裹的數組。 – 2011-06-01 20:30:49
非常感謝。 – 2011-06-01 20:36:25
在Java中,不可變類通常意味着它沒有「setter」,任何可以用「getter」訪問的字段也應該是不可變的。爲了讓您的數據進級開始,你需要有一個構造函數的值作爲參數:
public class MyClass { String something; int somethingElse; // The class can only be modified by the constructor public MyClass(String something, int somethingElse) { this.something = something; this.somethingElse = somethingElse; } // Access "something". Note that it is a String, which is immutable. public String getSomething() { return something; } // Access "somethingElse". Note that it is an int, which is immutable. public int getSomethingElse() { return somethingElse; } }
這是包裝的任何對象,以便能夠「大致」不可改變的一種方式。
所有不是'getters'的方法調用都會拋出異常。此代碼定義的吸氣劑作爲滿足這些條件的方法:
get
或is
void
返回類型)開始是的,吸氣劑方法可以突變一個對象。但是,如果你的代碼(或您使用的代碼)是這樣做的,你有一些更大的問題,請去得到一些幫助:)
代碼:
class ImmutableWrapper
public static <T> T wrap(T thing) {
return (T) Proxy.newProxyInstance(thing.getClass().getClassLoader(), new Class[]{thing.getClass()}, OnlyGettersInvocationHandler.instance);
}
private static class OnlyGettersInvocationHandler implements InvocationHandler {
public static InvocationHandler instance;
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
final String name = method.getName();
if ((args == null || args.length == 0)
&& (name.startsWith("get") || name.startsWith("is")
&& !method.getReturnType().equals(Void.class))) {
return method.invoke(proxy, args);
} else {
throw new UnsupportedOperationException("immutable object: " + proxy + ", cannot call " + name);
}
}
}
}
SomeClass myThing = ... create and populate some object ...
SomeClass myImmutableThing = ImmutableWrapper.wrap(myThing);
myImmutableThing.setValue('foo'); // throws Exception
myImmutableThing.whatever(); // throws Exception
myImmutableThing.getSomething(); // returns something
myImmutableThing.isHappy(); // returns something
到底是如何改變你的對象引用?你是否重新設定obj的價值?或者你是否在改變obj中的值? Java不應該允許你改變obj指向的內容。這就是最終變量的含義。爲了處理使obj的內容不可變,你需要編寫一個不可變的類,如下所述。 – justkt 2010-01-27 13:34:25