2015-11-18 48 views
3

我有一個方法需要多個參數,其中一些參數將在方法內部更改。有些被用作只讀。客戶端(調用這種方法的代碼的其他部分)提供對象實例作爲參數。Java語言構造來指示參數不會發生變異?

Java語言的構造有什麼可供選擇,讓我聲明的說法應該不能或不願或不能在方法內部發生突變。 Constrcuts像註釋或關鍵字,它告訴客戶端該方法不會更改在方法調用中用作參數的對象實例。還構造了這樣的情況,如果我(作爲這種方法的實現者)試圖在方法實現內意外地突變對象,將會生成編譯錯誤或警告。

我知道關鍵字final但這只是爲了確保引用不被更新。

不可變性不是解決方案,因爲在其他方法(或我的應用程序中的其他方法)中,我希望將該類型的實例設置爲可變的,只有在此方法調用中,我想給客戶端一個「承諾」 ,我不會改變他作爲參數提供的實例。

對參數進行深度複製或克隆或讓客戶端(調用者)執行此類操作並不是必需的,因爲它不是方法邏輯的一部分,無論如何都需要更改實例。我只是想知道這種語言是否有助於雙重檢查,這是不會發生的。

+0

你可以做深拷貝和傳遞。 – John

+0

一種骯髒的方式是使用[StackTraceElement的](http://stackoverflow.com/questions/421280/how-do-i-find-the-caller-of-a-method-using-stacktrace-or-reflection)提取上次調用的方法/類。如果從一個*不可接受的上下文*中調用此方法(setter方法),你可以拋出一個異常('UnsupportedOperation'?)。我其實不認爲這是一個好主意:P – TheLostMind

回答

4

沒有辦法定義一個只讀的參數(只是你已經提到的)。但是,您可以使用builder pattern構建傳遞的對象,這樣的內置對象只會有getter方法,所以不會有setter方法使其有效不變(注意,反射仍然可以用來修改其字段) 。

3

您正在尋找不變性final確保引用無法更新,但可變字段仍可以更改。通過創建類不變的實例,可以確保實例的值永不改變。

檢查strategy for defining immutable Objects

如果你不想讓你的實例不變,你仍然可以給客戶一個保證呈現給他們的對象不能被傳遞防守副本改變/深拷貝實例

+1

我認爲OP知道這一點。 – Mena

+0

@Mena - 我認爲OP只知道'final'字段而不知道*不可變實例*。此外,除了使用防禦性副本或使對象不可變,我沒有看到實際做到這一點的任何好方法。 – TheLostMind

+0

不變性是不是一個解決方案,因爲其他方法(或在我申請的其他地方),我想有類型的實例是可變的,只有在調用此方法,我wan't給一個「承諾」到客戶端,我不會改變自己的實例作爲參數 – StaticBug

3

在那裏沒有純粹的java解決方案。

正如您所提到的,final關鍵字將只確保沒有新的值可以分配給該參考。您可以使用

一個預防措施是克隆,或環繞你的可變參數視情況而定。

有一些(繁瑣)技術可用於深度克隆收集和映射(請參閱herehere以瞭解SO中的快速示例)。

最終,一個良好的介紹和深入的javadoc可以在這裏提供文件的適當水平。

相關問題