2016-12-28 16 views
5

JavaでC++のconstと似た何かを実現する方法はありますか?具体的には、私はjavaのConst関数の引数は?

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

のような機能を持っていると私は

  1. にしたい
  2. はそうでないことを強制し、それはそれは引数です変更しないことを署名に明確に引数を変更してください(できればコンパイル時ですが、ランタイムアサーションを挿入することもOKです)。

今私は、Javaは厳密に参照渡し(私はちょうど私がコースのit is pass-by-value or rather pass-by-copying-a-referenceを知って、からかってる)であることを知っています。つまり、Javaでは、メソッドを呼び出すと、参照がコピーされますが、その参照は同じオブジェクトの内容を指しています。クラスにパブリックフィールドまたはセッターがある場合、呼び出されたメソッドは、渡されたオブジェクトの内容をいつでも変更できます。例えば何かありますか?これを防ぐには@NotNullやツールのようなアノテーションを使用しますか?私はちょうど@Contract(pure = true)のようなJetBrainsアノテーションを見つけましたが、私は彼らが何らかのチェックを提供しているとは思いません。

+1

あなたは 'final'をパラメータに加えることができますが、これは初期化を防ぐだけで、' Vector'の内容を変更するメソッドとセッターを呼び出すことができます。アクセスを制限する必要がある場合は、 'Vector'を隠す不変クラスを作成する必要があります。基本的には、更新を防ぐためのすべてのメソッドを記述します(セッターを隠してゲッターをプリミティブ値に制限します) – AxelH

答えて

3

この方法ではパラメータが変更されないことは保証できません。オブジェクトを変更しないようにするには、オブジェクトを変更不可能にする必要があります。提供されたセッターなしで、内部で渡されるいくつかのラッパークラスを使用することができます。または、パッケージローカルメソッドを呼び出す必要がある場合は、setterをpackage-localにして、同じパッケージ内にいくつかのアクセスヘルパークラスを使用できます。

+0

getterには注意してください、これは更新可能なPOJOを返すかもしれません;)私たちは基本的に同じ考えを追加します – AxelH

+0

@AxelHはい、それ実装の詳細です、私はちょうど一般的な方法を提供した:) –

2

finalをパラメータに追加することはできますが、これにより初期化が妨げられるだけで、まだVectorの内容を変更するメソッドとセッタを呼び出すことができます。

これらのアクセスを制限する必要がある場合は、Vector,ラッパーを隠す不変クラスを作成する必要があります。基本的には、セッターを隠してゲッターをプリミティブ値に制限することで、更新を妨げるメソッドだけをリダイレクトし、インスタンスを戻すことでインスタンス内の値を変更することができます。

もちろん、劇的な解決策もあります。クローンベクターと彼のコンテンツ。誰かが一部の値を更新しようとしてもインスタンスを安全に保つ。これは、間違った値を使ってこの呼び出し中に問題になるだけですが、元のインスタンスは変更しません。

または、両方のソリューションを使用して、クローンインスタンスを返すラッパーを作成することができます(クローンを返すget(intインデックス)を提供するだけでよい)。このソリューションは、メモリ消費(必要なインスタンスだけを複製する)と制限的ゲッターの間の妥協点です。

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); 
} 
関連する問題