この記事は、主に次のようにJava文字列でオブジェクトを作成する問題を研究しています。
まず、変数とオブジェクトの参照の2つの概念を理解する必要があります。オブジェクトは通常、新しい介してヒープで作成され、文字列は単なる参照変数です。
すべての文字列は文字列オブジェクトです。文字列定数が大量に使用されるため、Javaで時間を節約するために、コンピレーション段階では、すべての文字列定数が文字列定数プールに配置されます。文字列定数プールの利点の1つは、同じストリングをマージしてスペースを占有できることです。
変数のアドレスをJavaで直接取得することはできませんが、==を使用して、2つの参照変数がアドレス、つまりオブジェクトを指しているかどうかを判断できます。
| スタックメモリ | ヒープメモリ |
|---|---|
| 基本タイプ、オブジェクトリファレンス(ヒープメモリアドレス) | 新しいによって作成されたオブジェクトと配列 |
| 高速アクセス速度 | スタックよりも遅いメモリ |
| データサイズは、宣言サイクル中に決定する必要があります | 割り当てられたメモリは、Java Virtual Machine Automatic Garbage Collectorによって管理されます。動的に割り当てられたメモリサイズ |
| 共有機能は、スタックに文字列がある場合、直接参照されます。そうでない場合は、価値を保存するための新しいスペースを開いてください | すべての新しいオブジェクトは、ヒープメモリに新しいオブジェクトを生成します。再利用は存在しません |
パッケージcom.demo.test; import java.lang.refllect.field; public class stringdemo {public static void main(string [] args){//この文字列オブジェクトがメモリに存在するかどうかを最初に探します。存在する場合は、この文字列オブジェクトを指します。 string str1 = "abc"; string str2 = "abc"; /* public string toString(){これを返します。 } */ string str3 = "abc" .toString(); //この文字列オブジェクトがすでにメモリに存在するかどうかに関係なく、新しいオブジェクトが作成されます。 string str4 = new String( "ABC"); string str5 = new String( "ABC"); string str6 = str5; string str7 = "a" + "b" + "c"; string str8 = "a" + "b" + new String( "c"); //文字列は不変の文字列オブジェクトであり、StringBuilderとStringBufferは可変文字列オブジェクト(内部の文字配列の長さは可変です)、StringBufferはスレッドセーフ、StringBuilderはThread-Safe String Str9 = new StringBuilder()。append( "a")。 string str10 = new stringbuffer()。append( "a")。append( "b")。append( "c")。toString(); System.out.println( "---------> =="); System.out.println( "---> 1"); System.out.println(str1 == str2); // true system.out.println( "---> 3"); System.out.println(str3 == str1); // true system.out.println( " - > 4"); System.out.println(str4 == str1); // false System.out.println(str4 == str3); // false System.out.println(str4 == str5); // false System.out.println(str4 == str6); // false system.out.out.out.println( " - - > 7"); System.out.println(str7 == str1); // true system.out.println(str7 == str3); // true system.out.println(str7 == str4); // false system.out.println( "---> 8"); System.out.println(str8 == str1); // false system.out.println(str8 == str3); // false System.out.println(str8 == str4); // false system.out.println(str8 == str7); // false system.out.out.out.println(str8 = = = = = = = = = = = = = = = = = = = = STAME); System.out.println(str9 == str1); // false system.out.println(str9 == str3); // false system.out.println(str9 == str4); // false system.out.println(str9 == str7); // false system.out.out.out.println(str9 = = str8); System.out.println(str10==str1);//false System.out.println(str10==str3);//false System.out.println(str10==str4);//false System.out.println(str10==str7);//false System.out.println(str10==str8);//false System.out.println(str10 == str9); // false system.out.println( "--------> equals"); System.out.println(str1.equals(str4)); // true system.out.println(str1.equals(str7)); // true system.out.println(str1.equals(str8)); // true system.out.println( "---------> hashcode"); /*ハッシュコード計算式:s [0]*31^(n-1) + s [1]*31^(n-2) + ... + s [n-1]したがって、ハッシュコードは同じであり、*/system.out.println(str1.hashcode()); system.out.println(str3.hashcode()); system.out.println(str4.hashcode()); system.out.println(str5.hashcode()); system.out.println(str6.hashcode()); system.out.println(str7.hashcode()); System.out.println( "-------->通常の変更値"); //文字列は不変のクラスです。文字列は、ヒープメモリ内の参照を指します。オブジェクト自体ではなく、オブジェクトのアドレスをヒープに保存します。値を文字列に割り当てることは、オブジェクト自体の代わりに参照オブジェクトを変更するだけですstr6 = "123"。 System.out.println(str5); // abc system.out.println(str6); // 123 system.out.println( "-------->変更値を反映します"); /*文字列の値を変更する必要がある場合、不可能ではありません。反射のみを使用できます。パブリックファイナルクラスの文字列は、java.io.serializable、comparable <string>、charsequence {//値が文字ストレージに使用されます。プライベートファイナルチャーバリュー[]; …} */ str6 = str5; try {field field = string.class.getDeclaredfield( "value"); // field field = str6.getClass()。getDeclaredField( "value"); if(!field.isaccessible()){field.setAccessible(true); } char [] value =(char [])field.get(str6);値[0] = '0'; System.out.println(str5); // 0bc System.out.println(str6); // 0bc} catch(nosuchfieldexception | securityexception | IllegalArgumentException | Illegalaccessexception e){e.printstacktrace(); } system.out.println( "-------> obj.toString()");オブジェクトobj = new object(); /* public string toString(){return getClass()。getName() + "@" + integer.tohexstring(hashcode()); } */system.out.println(obj.tostring()); // java.lang.object@15db9742 string [] arr1 = {"0"}; string [] arr2 = {"0"}; system.out.println(arr1.equals(arr2)); // false}}}要約します
上記は、Java String Creation Objectインスタンスの分析に関するものであり、すべての人に役立つことを願っています。興味のある友人は、このサイトの他の関連トピックを引き続き参照できます。欠点がある場合は、それを指摘するためにメッセージを残してください。このサイトへのご支援をありがとうございました!