ホームページ Java &#&チュートリアル Javaの文字列定数プールの詳細説明

Javaの文字列定数プールの詳細説明

Oct 16, 2018 pm 05:01 PM
Java文字列

この記事では、Java の文字列定数プールについて詳しく説明します。必要な方は参考にしていただければ幸いです。

Java 設計者は、最も基本的な参照データ型として、String のパフォーマンスを向上させるために文字列定数プールを提供します。では、文字列定数プールの具体的な原理は何でしょうか。次の 3 つの質問があります。文字列定数プールを理解するには:

文字列定数プールの設計意図は何ですか?

文字列定数プールはどこですか?

文字列定数プールを操作するにはどうすればよいですか?

文字列定数プールの設計上の考え方

a. 文字列の割り当ては、他のオブジェクトの割り当てと同様に時間がかかります。最も基本的なデータ型として、大量の文字列を頻繁に作成するため、スペースのコストがかかり、プログラムのパフォーマンスに大きな影響を与えます。

b. パフォーマンスを向上させ、メモリのオーバーヘッドを削減するために、JVM は文字列定数をインスタンス化するときにいくつかの最適化を行いました。

キャッシュ領域と同様に、文字列の文字列定数プールを開きます。

文字列定数を作成するときは、まず文字列が文字列定数プールに存在するかどうかを確認します。

文字列が存在する場合は、参照インスタンスを返します。存在しない場合は、文字列をインスタンス化してプールに入れます。

c. 実装の基礎

この最適化を実現するための基礎は、文字列が不変であり、データの競合を気にせずに共有できることです。

ランタイム インスタンスによって作成されたグローバル文字列定数プールにはテーブルがあり、プール内の一意の各文字列オブジェクトの参照が常に維持されます。つまり、常に文字列定数プールを参照します。したがって、定数プール内のこれらの文字列はガベージ コレクターによってリサイクルされません。

コード: 文字列定数プールから対応する文字列を取得

  String str1 = “hello”;
  String str2 = “hello”;
  System.out.printl("str1 == str2" : str1 == str2 ) //true

文字列定数プールはどこですか

解析時文字列定数プールの場所、まずヒープ、スタック、およびメソッド領域を理解します:

Javaの文字列定数プールの詳細説明

Heap

storedオブジェクトであり、各オブジェクトには対応するクラスが含まれます。

JVM には、すべてのスレッドで共有されるヒープ領域 (ヒープ) が 1 つだけあり、基本型とオブジェクト参照はヒープに格納されず、オブジェクト自体のみが格納されます。

オブジェクトはガベージ コレクターによってリサイクルされるため、サイズとライフ サイクルを決定する必要はありません

スタック

各スレッドにはスタック領域が含まれます。スタックにはスタック領域が 1 つだけあります 基本データ型のオブジェクトとカスタム オブジェクトへの参照 (オブジェクトではありません) を保存します

#各スタック内のデータ (元の型とオブジェクト参照) はプライベートです

スタックは基本型変数領域、実行環境コンテキスト、演算命令領域(ストレージ演算命令)の3つに分かれています。

データへの参照がない場合、データサイズとライフサイクルがわかります。 、データは自動的に消えます

メソッド領域

ヒープなどの静的領域はすべてのスレッドで共有されます

メソッド領域には次のものが含まれますプログラム全体で常に一意であるクラス、静的変数などの要素

メソッド領域に文字列定数プールが存在します

コード: スタック メソッド領域には、 strings

String str1 = “abc”;
String str2 = “abc”;
String str3 = “abc”;
String str4 = new String(“abc”);
String str5 = new String(“abc”);

Javaの文字列定数プールの詳細説明

文字列オブジェクトの作成

インタビューの質問: String str4 = new String("abc) によって作成されるオブジェクトの数")?

1. 定数プールに "abc" オブジェクトがあるかどうかを確認します。

存在する場合は、対応する参照インスタンスを返します。

存在しない場合は、対応するインスタンス オブジェクトを作成します。

2. ヒープに新しい String("abc") オブジェクトを作成します

3. オブジェクトのアドレスを str4 に割り当て、参照を作成します

したがって、定数プール内の "abc" リテラル 次に、2 つのオブジェクトを作成します。それ以外の場合は、オブジェクトを作成し、参照を作成します。

リテラルに基づいて、このようなさまざまな質問がよくあります。

String str1 = new String("A" " B") ; オブジェクトはいくつ作成されますか?

String str2 = new String("ABC") "ABC" ; オブジェクトはいくつ作成されますか? #str1:

文字列定数 プール: "A"、"B"、"AB": 3

ヒープ: new String("AB"): 1

参照: str1: 1

合計: 5

str2:
文字列定数プール: "ABC": 1
ヒープ: 新しい String("ABC"): 1

参照: str2: 1

合計: 3

コード: 基本型の変数と定数、変数と参照はスタックに保存され、定数は定数プールに保存されます
#

int a1 = 1;
int a2 = 1;
int a3 = 1;
public static int INT1 =1 ;
public static int INT2 =1 ;
public static int INT3 =1 ;

文字列定数プールの操作方法Javaの文字列定数プールの詳細説明

JVM が文字列定数プールをインスタンス化する場合

  String str1 = “hello”;
  String str2 = “hello”;
  System.out.printl("str1 == str2" : str1 == str2 ) //true
String.intern()

通过new操作符创建的字符串对象不指向字符串池中的任何对象,但是可以通过使用字符串的intern()方法来指向其中的某一个。java.lang.String.intern()返回一个保留池字符串,就是一个在全局字符串池中有了一个入口。如果以前没有在全局字符串池中,那么它就会被添加到里面

// Create three strings in three different ways.
    String s1 = "Hello";
    String s2 = new StringBuffer("He").append("llo").toString();
    String s3 = s2.intern();
    // Determine which strings are equivalent using the ==
    // operator
    System.out.println("s1 == s2? " + (s1 == s2)); // false
    System.out.println("s1 == s3? " + (s1 == s3)); // true

字面量和常量池初探

字符串对象内部是用字符数组存储的,那么看下面的例子:

String m = "hello,world";
String n = "hello,world";
String u = new String(m);
String v = new String("hello,world");

1.会分配一个11长度的char数组,并在常量池分配一个由这个char数组组成的字符串,然后由m去引用这个字符串

2.用n去引用常量池里边的字符串,所以和n引用的是同一个对象

3.生成一个新的字符串,但内部的字符数组引用着m内部的字符数组

4.同样会生成一个新的字符串,但内部的字符数组引用常量池里边的字符串内部的字符数组,意思是和u是同样的字符数组

使用图来表示的话,情况就大概是这样的(使用虚线只是表示两者其实没什么特别的关系):

Javaの文字列定数プールの詳細説明


测试demo:

 String m = "hello,world";        
 String n = "hello,world";        
 String u = new String(m);        
 String v = new String("hello,world");        
 System.out.println(m == n); //true         
 System.out.println(m == u); //false        
 System.out.println(m == v); //false        
 System.out.println(u == v); //false

结论:

m和n是同一个对象

m,u,v都是不同的对象

m,u,v,n但都使用了同样的字符数组,并且用equal判断的话也会返回true

以上がJavaの文字列定数プールの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

ハッシュマップはJavaで内部的にどのように機能しますか? ハッシュマップはJavaで内部的にどのように機能しますか? Jul 15, 2025 am 03:10 AM

HashMapは、Javaのハッシュテーブルを介してキーと値のペアストレージを実装し、そのコアはデータの位置をすばやく配置することにあります。 1.最初にキーのHashCode()メソッドを使用して、ハッシュ値を生成し、ビット操作を介して配列インデックスに変換します。 2。異なるオブジェクトは、同じハッシュ値を生成し、競合をもたらす場合があります。この時点で、ノードはリンクされたリストの形式で取り付けられています。 JDK8の後、リンクされたリストが長すぎ(デフォルトの長さ8)、効率を改善するために赤と黒の木に変換されます。 3.カスタムクラスをキーとして使用する場合、equals()およびhashcode()メソッドを書き直す必要があります。 4。ハッシュマップは容量を動的に拡大します。要素の数が容量を超え、負荷係数(デフォルト0.75)を掛けた場合、拡張して再ハッシュします。 5。ハッシュマップはスレッドセーフではなく、マルチスレッドでconcuを使用する必要があります

Java仮想スレッドパフォーマンスベンチマーク Java仮想スレッドパフォーマンスベンチマーク Jul 21, 2025 am 03:17 AM

仮想スレッドには、非常に並行したシナリオとIO集約型シナリオに大きなパフォーマンスの利点がありますが、テスト方法と適用可能なシナリオに注意を払う必要があります。 1.正しいテストでは、実際のビジネス、特にIOブロッキングシナリオをシミュレートし、JMHやガトリングなどのツールを使用してプラットフォームスレッドを比較する必要があります。 2。スループットのギャップは明らかであり、スケジューリングがより軽量で効率的であるため、100,000の同時リクエストよりも数倍から10倍高くなる可能性があります。 3。テスト中に、盲目的に高い並行性数を追求し、非ブロッキングIOモデルに適応し、レイテンシやGCなどの監視インジケーターに注意を払う必要があります。 4.実際のアプリケーションでは、Webバックエンド、非同期タスク処理、および多数の同時のIOシナリオに適していますが、CPU集約型タスクはプラットフォームスレッドまたはForkjoinpoolに依然として適しています。

WindowsでJava_home環境変数を設定する方法 WindowsでJava_home環境変数を設定する方法 Jul 18, 2025 am 04:05 AM

tosetjava_homeonwindows、firstlocatethejdkinstallationpath(例:c:\ programfiles \ java \ jdk-17)、thencreateSystemenvironmentvaria blenamedjava_homewiththatpath.next、updatethepathvariablebyadding%java \ _home%\ bin、andverifythesetusingingingjava-versionandjavac-v

JDBCを使用してJavaのトランザクションを処理する方法は? JDBCを使用してJavaのトランザクションを処理する方法は? Aug 02, 2025 pm 12:29 PM

JDBCトランザクションを正しく処理するには、最初に自動コミットモードをオフにし、次に複数の操作を実行し、結果に応じて最終的にコミットまたはロールバックする必要があります。 1。CONN.SETAUTOCOMMIT(FALSE)を呼び出して、トランザクションを開始します。 2。挿入や更新など、複数のSQL操作を実行します。 3。すべての操作が成功した場合はconn.commit()を呼び出し、データの一貫性を確保するために例外が発生した場合はconn.rollback()を呼び出します。同時に、リソースを使用してリソースを管理し、例外を適切に処理し、接続を密接に接続するために、接続の漏れを避けるために使用する必要があります。さらに、接続プールを使用してセーブポイントを設定して部分的なロールバックを達成し、パフォーマンスを改善するためにトランザクションを可能な限り短く保つことをお勧めします。

Java Microservices Serviceメッシュ統合 Java Microservices Serviceメッシュ統合 Jul 21, 2025 am 03:16 AM

ServiceMeshは、Java Microservice Architectureの進化のための避けられない選択であり、その中心はネットワークロジックとビジネスコードの分離にあります。 1. ServiceMeshは、ビジネスに焦点を当てるために、サイドカーエージェントを介したロードバランシング、ヒューズ、監視、その他の機能を処理します。 2。ISTIO使節は中程度および大規模なプロジェクトに適しており、Linkerdは軽量で小規模な試験に適しています。 3. Java Microservicesは、発見とコミュニケーションのために、装い、リボン、その他のコンポーネントを閉鎖し、IStiodに引き渡す必要があります。 4.展開中にサイドカーの自動注入を確保し、トラフィックルールの構成、プロトコル互換性、ログトラッキングシステムの構築に注意を払い、増分移行とコントロール前の監視計画を採用します。

Javaにリンクリストを実装します Javaにリンクリストを実装します Jul 20, 2025 am 03:31 AM

リンクリストを実装する鍵は、ノードクラスを定義し、基本操作を実装することです。 firstデータや次のノードへの参照を含むノードクラスを作成します。次に、LinkedListクラスを作成し、挿入、削除、および印刷機能を実装します。 deppentedメソッドは、テールにノードを追加するために使用されます。 printlistメソッドを使用して、リンクリストのコンテンツを出力します。 dreatewithValueメソッドは、指定された値を持つノードを削除し、ヘッドノードと中間ノードのさまざまな状況を処理するために使用されます。

Javaの日付をSimpleDateFormatでフォーマットする方法は? Javaの日付をSimpleDateFormatでフォーマットする方法は? Jul 15, 2025 am 03:12 AM

SimpledateFormatを作成して使用するには、NewsimpledateFormat( "yyyy-mm-ddhh:mm:ss")などの形式の文字列を渡す必要があります。 2。ケースの感受性に注意を払い、混合シングルレター形式とYyyyとDDの誤用を避けます。 3。SimpleDateFormatはスレッドセーフではありません。マルチスレッド環境では、新しいインスタンスを作成するか、毎回Threadlocalを使用する必要があります。 4.解析方法を使用して文字列を解析する場合、parseexceptionをキャッチし、結果にタイムゾーン情報が含まれていないことに注意する必要があります。 5。DateTimeFormatterとLOを使用することをお勧めします

高度なJavaコレクションフレームワークの最適化 高度なJavaコレクションフレームワークの最適化 Jul 20, 2025 am 03:48 AM

Java Collection Frameworkのパフォーマンスを向上させるために、次の4つのポイントから最適化できます。1。アレイリストへの頻繁なランダムアクセス、ハッシュセットへのクイック検索、同時環境の同時ハッシュマップなど、シナリオに従って適切なタイプを選択します。 2.初期化中に容量と荷重係数を合理的に設定して、容量の拡張オーバーヘッドを減らしますが、メモリ無駄を避けます。 3.不変のセット(list.of()など)を使用して、一定または読み取り専用データに適したセキュリティとパフォーマンスを改善します。 4.メモリの漏れを防ぎ、弱い参照またはプロのキャッシュライブラリを使用して、長期生存セットを管理します。これらの詳細は、プログラムの安定性と効率に大きく影響します。

See all articles