67

私の目標は、Java オブジェクトを不変にすることです。クラスがありStudentます。不変性を実現するために、次の方法でコーディングしました。

public final class Student {

private String name;
private String age;

public Student(String name, String age) {
    this.name = name;
    this.age = age;
}

public String getName() {
    return name;
}

public String getAge() {
    return age;
}

}

私の質問は、Studentクラスの不変性を達成するための最良の方法は何ですか?

4

16 に答える 16

69

あなたのクラスは厳密に言えば不変ではなく、事実上不変です。不変にするには、次を使用する必要がありますfinal

private final String name;
private final String age;

違いは微妙に思えるかもしれませんが、マルチスレッド コンテキストでは大きな違いを生む可能性があります。不変クラスは本質的にスレッドセーフであり、実質的に不変クラスは、安全に公開されている場合にのみスレッドセーフです。

于 2013-08-12T18:35:20.897 に答える
58

不変クラスを作成するために考慮しなければならないことがいくつかあります。

  • あなたのクラスを作るfinal- あなたはすでに持っています
  • すべてのフィールドprivatefinal作成し、コードに適切な変更を加えます
  • インスタンスの状態を変更するメソッドを提供しないでください
  • List、またはのような変更可能なフィールドがクラスにある場合Date、それらfinalを作成するだけでは不十分です。gettersメソッドの呼び出しによって状態が変更されないように、から防御的なコピーを返す必要があります。

4 番目のポイントとしてDate、クラスにフィールドがあるとします。そのフィールドのゲッターは次のようになります。

public Date getDate() {
    return new Date(this.date.getTime());
}

可変フィールド自体がいくつかの可変フィールドで構成されており、それが他の可変フィールドを含むことができる場合、防御的なコピーを作成することは頭痛の種になる可能性があります。その場合、それぞれのコピーを繰り返し作成する必要があります。この可変フィールドの反復コピーをDeep Copyと呼びます。

自分でディープコピーを実装するのは面倒かもしれません。しかし、その問題は別として、ディープ ディフェンシブ コピーを作成する必要性に陥った場合は、クラスの設計を再度検討する必要があります。

于 2013-08-12T18:39:18.263 に答える
3

finalキーワードを使用:

private final String name;
private final String age;
于 2013-08-12T18:34:44.677 に答える
3

プリミティブ データ型では、変数を非公開にし、セッター メソッドを使用しないようにします。クラスにオブジェクトのコレクションがある場合は?

コレクションオブジェクトでクラスを不変にするには?

extends コレクション クラスを使用して独自のコレクション オブジェクトを作成し、プライベート変数に従い、セッター メソッドは使用しません。または、コレクション オブジェクトのクローン オブジェクトを返します。

public final class Student {

private StudentList names;//Which is extended from arraylist

public Student() {
names = DAO.getNamesList()//Which will return All Student names from Database  its upto you how you want to implement.
}

public StudentList getStudentList(){
return names;//you need to implement your own methods in StudentList class to iterate your arraylist; or you can return Enumeration object.
}

public Enumeration getStudentNamesIterator(
Enumeration e = Collections.enumeration(names);
return e;
}

public class StudentList extends ArrayList {

}
于 2015-04-17T09:27:12.830 に答える
2

これは問題ありませんが、フィールドも作成しfinalます。

また、年齢を文字列ではなくintorにします。double

于 2013-08-12T18:34:53.803 に答える
1

答えるには遅すぎますが、この質問をしている他の人々を助けるかもしれません.

  1. 不変オブジェクトの状態は、構築後に変更することはできません。変更すると、新しい不変オブジェクトが作成されます。
  2. Immutable クラスのすべてのフィールドは final でなければなりません。
  3. オブジェクトは適切に構築されている必要があります。つまり、構築プロセス中にオブジェクト参照がリークしてはなりません。
  4. 親クラスの不変性を変更するためにサブクラスを制限するために、オブジェクトは final でなければなりません。

このリンクはもっと役立つと思います 続きを読む: http://javarevisited.blogspot.com/2013/03/how-to-create-immutable-class-object-java-example-tutorial.html#ixzz40VDQDDL1

于 2016-02-18T08:32:59.020 に答える
0

これはすでに不変です。セッターを作成していないため、一度初期化すると内容を変更できません。変数に final キーワードを追加できます。

于 2013-08-12T18:35:23.810 に答える
0

finalいくつかのフィールドを設定するときにすべての変数を作成しStudent、のように新しく設定された値で新しいオブジェクトへの参照を返すようにしStringます。

于 2013-08-12T18:36:27.377 に答える
0

この例に示されているガイドラインに従うだけです (Google での最初の結果): http://www.javapractices.com/topic/TopicAction.do?Id=29

于 2013-08-12T18:36:30.943 に答える
0

Java でクラスを不変にするのに役立ついくつかのルールを次に示します。 1. 不変オブジェクトの状態は構築後に変更できません。2. Immutable クラスのすべてのフィールドは final でなければなりません。3. オブジェクトは適切に構築されている必要があります。つまり、構築プロセス中にオブジェクト参照がリークしてはなりません。4. 親クラスの不変性を変更するためのサブクラスを制限するために、オブジェクトは final でなければなりません。

例:

public final class Contacts {

private final String name;
private final String mobile;

public Contacts(String name, String mobile) {
    this.name = name;
    this.mobile = mobile;
}

public String getName(){
    return name;
}

public String getMobile(){
    return mobile;
}

}

このリンクを参照してください: http://javarevisited.blogspot.in/2013/03/how-to-create-immutable-class-object-java-example-tutorial.html

于 2014-12-02T10:13:40.013 に答える
-2

クラスまたは変数を final にするだけで十分です

Public final class constants
{
  private final String name;
  private final String mobile;

  // code
}
于 2015-01-22T07:15:54.133 に答える