如果將對象引用傳遞給某個方法,是否可以將該對象設置爲只讀方法?是否可以將某個對象設置爲只讀方法
回答
不嚴格地說。也就是說,可以改變對象的引用不能變成不能改變對象的引用。此外,除了使用約定之外,沒有辦法表示類型是不可變的或可變的。
確保某種形式的不變性的唯一功能是final
領域 - 寫一次,他們不能被修改。
也就是說,有設計類的方法可以防止不需要的突變。這裏有一些技巧:
Defensive Copying。傳遞一個對象的副本,這樣如果它發生了變異,它不會破壞你的內部不變量。
使用訪問修飾符和/或接口僅暴露只讀方法。您可以使用訪問修改(
public
/private
/protected
),可能與接口相結合,以便只有某些方法對其他對象可見。如果暴露的方法本質上是隻讀的,那麼您是安全的。使您的對象默認爲不可變。對象的任何操作實際上都返回對象的副本。
另外,還要注意的是,在SDK API都有有時返回一個對象的不變版本的方法,例如Collections.unmodifiableList
。試圖改變一個不可變列表會引發異常。這不會在靜態(在靜態類型系統的編譯期)強制執行不變性,但是它是動態(在運行時)動態強制執行的廉價而有效的方法。
有很多關於Java擴展的研究建議,以更好地控制混疊和可訪問性。例如,添加一個readonly
關鍵字。據我所知,它們中沒有一個計劃包含在未來版本的Java中。你可以看看這些指針如果你有興趣:
- Why We Should Not Add ''Read-Only'' to Java (yet) - 它列出,比較大部分建議
- The Checker Framework: Custom pluggable types for Java - 一種非侵入性的方式與不變的擴展型系統,特別是類型。
Checker框架非常有趣。在Checker框架中,查看通用Universe類型檢查器,IGJ不變性檢查器和Javari不變性檢查器。該框架使用註釋工作,所以它不是侵入性的。
只讀pdf遭受鏈接腐爛。 – flup
不可以,但你可以嘗試傳遞之前,克隆的對象,所以該方法所做的任何更改都不會影響原來的對象。
不,不是沒有裝飾,合成,克隆等
有這個問題並沒有一般機制。您需要編寫特殊代碼來實現它,比如編寫一個不可變的包裝器(請參閱Collections.unmodifiableList
)。
您可以定義對象的所有參數final
但使只讀到每個人的對象。
你可以通過克隆Object
的方法,像這樣的第一條語句實現在大多數情況下,類似的事情......
public void readOnlyMethod(Object test){
test = test.clone();
// other code here
}
所以,如果你叫readOnlyMethod()
,並通過在任何Object
,一將採取Object
的克隆。該克隆使用與該方法的參數相同的名稱,因此沒有意外更改原始Object
的風險。
這需要對象真正地實現'clone',因爲這是一個可編輯的API,所以現代的類很少會受到它的困擾。 –
正確。不過,我希望大多數核心Java類應該正確實現'clone()',所以這將覆蓋大多數情況。它可能與您將獲得只讀參數一樣近。 – wattostudios
'Collections.unmodifiableList'如何來自核心API(不克隆)。 –
取決於您希望執行規則的位置。如果您正在協作處理項目,請使用final
並附帶評論,告訴下一個人他們不打算修改此值。否則,你會不會只是寫方法而不是觸摸對象?
public static void main(String[] args) {
cantTouchThis("Cant touch this");
}
/**
*
* @param value - break it down
*/
public static void cantTouchThis(final String value) {
System.out.println("Value: " + value);
value = "Nah nah nah nah"; //Compile time error
}
所以專門來此方法,值將不會被寫入,它是在編譯時強制使該解決方案非常強大。在此方法的範圍之外,對象保持不變,而不必創建任何類型的包裝器。
private boolean isExecuteWriteQueue = false;
public boolean isWriting(){
final boolean b = isExecuteWriteQueue;
return b;
}
使其實現一個接口,它只有只讀方法(沒有setter方法),這給出了一個對象的副本(道路只複製),並返回接口的只讀實例,而不是返回實例一個對象本身
- 1. 是否可以將模塊的複選框設置爲「只讀」?
- 2. 是否可以將Range對象設置爲「向後選擇」?
- 3. 是否可以在unix上爲自己設置只讀?
- 4. 是否可以將LinqDataSource.OrderBy設置爲方法的結果?
- 5. 是否可以在javascript中將對象的屬性值設置爲對象?
- 6. 是否可以使某個HashMap的某些特定鍵爲只讀?
- 7. 是否可以將DynamicResource設置爲TargetNullValue?
- 8. 是否可以使用編組將JavaScript回調方法設置爲C#方法?
- 9. 是否可以將另一個類的方法設置爲NSInvocation對象的選擇器屬性?
- 10. 根據單個對象對某個方法的響應,是否可以對對象列表進行排序?
- 11. 是否可以調用實現某個接口的所有對象的方法?
- 12. Google存儲對象是否可以設置爲最大年齡?
- 13. C#是否可以將稱爲方法的對象另存爲另一個對象作爲參考節點
- 14. 是否可以在init-called塊中設置只讀屬性?
- 15. 是否可以將DirectX中的所有Alpha設置爲某個值,如0.75?
- 16. 將asptextbox設置爲只讀
- 17. 是否可以將對象的方法發送給函數?
- 18. 是否可以傳遞Object對象作爲方法參數
- 19. 將方法設置爲對象或甚至將方法參數設置爲對象意味着什麼?
- 20. 一個對象的方法是否可以作用於自己?
- 21. 使用Html.TextBoxFor時,可以將文本框設置爲只讀嗎?
- 22. 是否可以將表只讀爲休眠狀態?
- 23. 是否可以將HSQLDB模式更改爲只讀模式?
- 24. 只能將網頁設置爲只讀?
- 25. 是否可以將對象「擴展」爲一個函數?
- 26. 是否可以將多行作爲單個DOM對象處理?
- 27. 是否可以強制AR對象ID從某個值開始?
- 28. 我可以知道AppleScript對象是否具有某個屬性?
- 29. 是否可以將多個模型設置爲MVCForm?
- 30. Ruby:是否可以將if語句==設置爲2個變量?
有一箇舊的,但仍然很好的資源:http://www.cs.uwm.edu/~boyland/papers/readonly-talk.pdf –
如何存儲對象的引用,克隆它並且如果沒有改變,不時比較一下? –