1。不変のカテゴリの紹介
不変のクラス:いわゆる不変のクラスは、このクラスのインスタンスが作成されると、そのメンバー変数値を変更できないことを意味します。たとえば、JDKに付属する多くの不変のクラス:Interger、Long、Stringなど。
変数クラス:不変のクラスと比較して、Mutableクラスは、インスタンスを作成した後にメンバー変数値を変更できます。開発で作成されたほとんどのクラスは、可変クラスに属します。
2。不変のクラスの利点
可変クラスと不変のクラスの違いについて話した後、不変のクラスがある理由をさらに理解する必要がありますか?このような機能はJavaにどのような利点をもたらしますか?
1。スレッドの安全
不変のオブジェクトはスレッドセーフであり、スレッド間で共有できます。オブジェクトの値を変更できないため、同期の問題を確保するために特別なメカニズムを使用する必要はありません。同時のメカニズムを使用してメモリの一貫性の問題を確保する必要がないため、同時のメカニズムを使用する必要がないため、同時エラーの可能性を減らすことができます。
2。構築、使用、テストが簡単です
3 ....
不変のクラス設計方法
不変のクラスを設計するために、私は個人的に次の原則を要約します。
1.クラスに最終的な修飾子を追加して、クラスが継承されていないことを確認します。
クラスを継承できる場合、継承クラスが親クラスのメソッドをオーバーライドし、継承クラスがメンバーの変数値を変更できる限り、クラスの不変性メカニズムを破壊します。その後、子クラスが親クラスとして表示されると、現在のクラスが可変であるかどうかは保証できません。
2.すべてのメンバー変数がプライベートである必要があり、最終的な変更が追加されていることを確認してください
このようにして、メンバー変数が変更できないことを保証します。しかし、これを行うには十分ではありません。なぜなら、それがオブジェクトメンバー変数である場合、その値を外部から変更することが可能だからです。したがって、4番目のポイントはこの欠点を補います。
3.セッターを含むメンバー変数を変更する方法は提供されていません
他のインターフェイスを介してメンバー変数の値を変更したり、不変の機能を破壊したりしないでください。
4。コンストラクターを介してすべてのメンバーを初期化し、ディープコピー(ディープコピー)を実行します
コンストラクターによって渡されたオブジェクトがメンバー変数に直接割り当てられている場合、着信オブジェクトを変更することで変更できます。これにより、内部変数の値が変更されます。例えば:
パブリックファイナルクラスImmutabledemo {private final int [] myArray; public Immutabledemo(int [] array){this.myarray = array; // 間違っている } }この方法では、不変性を保証できません。 MyArrayと配列は同じメモリアドレスを指します。ユーザーは、Immutabledemo以外の配列オブジェクトの値を変更することにより、MyArray内の値を変更できます。
内部値が変更されていないことを確認するために、深さコピーを使用して新しいメモリを作成して着信値を保存できます。それを行うための正しい方法:
パブリックファイナルクラスmyimmutabledemo {private final int [] myArray; public myimmutabledemo(int [] array){this.myarray = array.clone(); }}5.ゲッターメソッドでは、オブジェクト自体を直接返すのではなく、オブジェクトをクローンしてオブジェクトのコピーを返します。
また、このアプローチはオブジェクトの漏れを防ぎ、ゲッターを介して内部可変メンバーオブジェクトを取得した後、メンバー変数の直接動作を防ぎ、メンバー変数の変更をもたらします。
IV。文字列オブジェクトの不変性
メモリ作成後に文字列オブジェクトを変更することはできません。不変のオブジェクトの作成は、一般に上記の5つの原則を満たしています。文字列コードの実装方法を見てみましょう。
パブリックファイナルクラスのstringimplements java.io.serializable、comparable <string>、charsequence {/**値は文字ストレージに使用されます。 */プライベート最終char値[];/**オフセットは、使用されるストレージの最初のインデックスです。 */private final int offset;/**カウントは文字列内の文字の数です。 */private final int count;/**文字列のハッシュコードをキャッシュ*/private int hash; //デフォルトは0 ..public string(char value []){this.value = arrays.copyof(value、value.length); //ディープコピー操作} ... public char [] tochararray(){//クラスの初期化の順序の問題のためにarrays.copyofを使用できませんresult result [] = new char [value.length]; system.arraycopy(value、0、result、0、value.length); return result;} ... ...上記のコードに示すように、次の設計の詳細を観察できます。
1.ストリングクラスは最終的に変更され、継承することはできません
2。文字列のすべてのメンバーはプライベート変数として設定されます
3.値セッターは存在しません
4。そして、値を設定し、最終的にオフセットします。
5.変数配列値[]を渡すときは、値を内部変数に直接コピーする代わりにコピーします。
6.値を取得すると、オブジェクト参照を直接返すのではなく、オブジェクトのコピーを返します。
これは、上記で要約された不変型の特性と一致しており、文字列タイプが不変のクラスであることも保証されます。
5.文字列オブジェクトの不変性の利点と短所
前のセクション分析から、文字列データは不可能であるため、このような機能を設定することの利点は何ですか?次のように要約しました。
1。文字列定数プールの要件。
文字列定数プールは、一定のプールでいくつかの文字定数を再利用でき、毎回同じオブジェクトを再現することを避け、ストレージスペースを保存します。ただし、文字列が可変の場合、同じコンテンツの文字列は、定数プールの同じメモリ空間も指しています。変数がそのメモリの値を変更すると、他のトラバース値も変更されます。したがって、一定のプール設計の当初の意図に準拠していません。
2。スレッド安全上の考慮事項。
同じ文字列インスタンスは、複数のスレッドで共有できます。このようにして、スレッドの安全性の問題のために同期を使用する必要はありません。文字列はスレッドセーフです。
3。クラスローダーは文字列を使用する必要があり、不変性はセキュリティを提供して、正しいクラスがロードされるようにします。たとえば、java.sql.connectionクラスをロードすると、この値がmyhacked.connectionに変更されると、データベースに不明な損傷が発生します。
4。ハッシュマッピングとキャッシュをサポートします。
文字列は不変であるため、ハッシュコードは作成されたときにキャッシュされ、再計算する必要はありません。これにより、文字列はマップ内のキーとして非常に適切になり、文字列の処理速度は他のキーオブジェクトよりも高速になります。これが、ハッシュマップのキーが頻繁に文字列を使用する理由です。
欠点:
1.文字列オブジェクトの値を変更する必要がある場合、多数の文字列オブジェクトが作成されます。
6。文字列オブジェクトは本当に不変ですか?
Stringオブジェクトは値を最終的に設定しますが、メンバー変数がさまざまなメカニズムを通じて変更できないことも保証します。ただし、反射メカニズムによって変更される可能性があります。例えば:
//文字列「Hello World」を作成し、参照SString s = "Hello World"に割り当てます。 System.out.println( "s =" + s); // hello world //文字列クラスで値フィールドを取得しますfield field valuefield ofstring = string.class.getDeclaredfield( "value"); = '_'; system.out.println( "s =" + s); //こんにちは世界
印刷の結果は次のとおりです。
s = hello worlds = hello_world
文字列の値が変更されたことがわかりました。つまり、いわゆる「不変」オブジェクトは、反射によって変更できます。
要約します
不変のクラスは、インスタンスが作成された後に変更できないメンバートラバーサルの値です。この機能により、不変のクラスはスレッドセーフ機能を提供できますが、オブジェクト作成のオーバーヘッドももたらします。属性の各変更は、新しいオブジェクトを再作成することです。 JDKはまた、整数、二重、弦などの多くの不変のクラスを提供します。文字列の不変の特性は、主に一定のプーリング、糸の安全性、クラスの負荷のニーズを満たすためです。不変のクラスの合理的な使用は、大きな利益をもたらす可能性があります。
上記は、Java(不変)の不変のメカニズムと、編集者が紹介した弦の不変性(推奨)です。それがあなたに役立つことを願っています。ご質問がある場合は、メッセージを残してください。編集者は時間内に返信します。 wulin.comのウェブサイトへのご支援ありがとうございます!