2016-12-28 73 views
5

有沒有辦法在Java中實現類似於C++的const的東西?具體而言,我有一個像在Java中const函數參數?

private static Vector2 sum(Vector2 vec1, Vector2 vec2) { 
    return vec1.cpy().add(vec2); 
} 

的功能,我想

  1. 使簽名,它不會修改它的參數,
  2. 執行它不明確修改它的參數(最好在編譯時,但插入運行時斷言也可以)。

現在我知道java是嚴格通過引用(我只是在逗弄,我知道當然是it is pass-by-value or rather pass-by-copying-a-reference)。我的意思是在Java中,當你調用一個方法時,引用被複制,但是引用指向相同的對象內容。如果一個類具有公共字段或setter,則被調用方法總是可以修改傳遞對象的內容。有沒有例如註釋如@NotNull或工具來防止這種情況?我剛剛發現了像@Contract(pure = true)這樣的JetBrains註釋,但我認爲他們不提供任何檢查。

+1

您可以在參數中添加'final',但這隻會阻止對這些參數的初始化,您仍然可以調用方法和setter來修改'Vector'的內容。如果你需要限制對這些的訪問,你可能需要創建一個隱藏'Vector'的不可變類。基本上它會寫每一個方法來防止更新(隱藏setter並將getter限制爲原始值) – AxelH

回答

3

您不能保證該方法不會更改參數。如果你想避免改變對象,你應該使它不可變。你可以使用一些包裝類,而不提供setter。或者,如果您需要調用某些軟件包本地方法,則可以使您的setter軟件包在本地並在相同的軟件包中使用某些訪問幫助程序類。

+0

注意getter,這可能會返回一個可以更新的POJO;)我們基本上添加相同的想法 – AxelH

+0

@AxelH是啊,它是實施的細節,我只是提供了一個通用的方式:) –

2

您可以將final添加到參數中,但這隻會阻止對這些參數的初始化,您仍然可以調用修改Vector內容的方法和setter。

如果需要限制訪問這些,你可能需要創建一個不可改變的類隱藏Vector包裝。基本上它只會重定向阻止任何更新的方法,方法是隱藏setter並將getter限制爲原始值,並返回實例,以便更改其中的值。

當然,也有一些大問題的解決辦法,你可以用克隆這個Vector和他的內容。即使有人試圖更新某些值,也要保證實例的安全。在調用期間,這隻會是一個問題,使用錯誤的值,但會保持原始實例不變。或者你可以同時使用這兩種解決方案,創建一個返回克隆實例的包裝器(只需要提供一個返回克隆的get(int index))。該解決方案是內存消耗(僅克隆需要的實例)和限制性獲取器之間的折中。

0

在Java中,唯一能做到這一點的方法是具有隻讀接口以及可變接口。這不易於維護,const會更好,但它不可用。您可以編寫

interface ReadOnlyVector<T> { 
    int size(); 
    // getter methods 
    T get(int n); 

    default ReadOnlyVector<T> add(ReadOnlyVector<T> v) { 
     // add two vectors are create a new one. 
    } 
} 

interface Vector<T> extends ReadOnlyVector<T> { 
    // mutating methods. 
    void add(T t); 
} 
相關問題