web-dev-qa-db-ja.com

可変オブジェクト-セッターとゲッター

この種のセッターメソッドを使用することは良い習慣ですか?プリミティブ型の場合は明らかに問題ありませんが、可変オブジェクトへの参照を保持するフィールドのセッターがある場合、これはうまくいかない可能性があります-呼び出し元がsetFieldメソッドに渡した後にオブジェクトを変更する可能性があります。

_class Myclass{
   private MyOtherClass field;

   public setField(MyOtherClass field){
      this.field = field;
   }
}
_

単にclone()を呼び出すのは正しいことですか(MyOtherClassにプリミティブ型のフィールドのみがあると仮定)。

_public setField(MyOtherClass field) {
    this.field = field.clone();
}
_
4
user4205580

クラスがデータ構造である場合、明らかにそうするのは問題ありません。 Java Mapには、参照を格納するputメソッドがあります。その参照を変更した場合、Map.get()を呼び出すと、変更されたオブジェクトが返されます。

クラスが車で、タイヤを設定している場合、問題はそこにあります。タイヤを設定し、プログラムの別の部分で変更するとどうなりますか?この場合(副作用がある場合)、結果に一貫性がない場合、いいえ、setterはそこにあるべきではありません。

あなたが注意する必要がある場合とそれが完全に有効である場合があるので、あなたが尋ねることは少し広いと思います。そのタイプのセッターが存在し、Javaのあちこちにあります。

副作用を避けたい場合は、おそらくより良い解決策は、不変のクラスを渡すことです(そのフィールドはすべてfinalです)。 APIを使用している場合、セッターがオブジェクトのクローンを作成することを期待することはできません。

例:

Personクラスがあります。彼はJobPlaceを持っていても持っていなくてもかまいません。あなたがそれを作成するときに人が持つつもりの仕事を知っていますか?おそらくない。また、その人は転職できますか?承知しました。

これはperson.setJob(job)を正当化します。今、その人は彼の仕事への参照を持っていますが、仕事自体が変更されるとどうなりますか?たとえば、会社は名前を変更できます。 Personは、機能するJobPlaceのインターフェイスを知っているだけでよいため、ジョブ自体が変更される可能性があり、複数のPersonJobPlaceへの同じ参照を保持している場合、 1か所でのみ変更する必要があります。

3
Fermin Silva