[Java] String Constant Pool


https://www.baeldung.com/java-string-constant-pool-heap-stackの内容を参照

0. Java Constant Pool

  • Javaは、Heap上で元のデータの定数プールを実行します.
  • はメモリを節約するために使用され、コンパイルフェーズで新しく宣言された定数の値が定数プールの値と同じである場合、heapのより多くのメモリを使用せずに参照アドレスを返します.
  • 1.JavaのStringは元のタイプではありません


    Javaを使用している場合は、==演算子を使用して文字列比較を行うことはできません.
    JavaのStringは元のタイプのオブジェクトではないため、文字列を比較オブジェクト参照アドレス(参照)の==演算子として比較すると、必要な結果が得られない可能性があります.
    しかし、以下のコードで==演算子を使うとどうなりますか?
    public class Main {
        public static void main(String[] args) {
            String cat1 = "cat";
            String cat2 = "cat";
    
            System.out.println(cat1 == cat2);
        }
    }
    上記の説明ではfalseを出力する必要がある場合があります.同じ内容の文字列でも参照のアドレスが異なるためです.
    ただし、実行時にはtrueとして出力されます.

    2. String Constant Pool


    JVMは、オブジェクトの参照アドレスをStackにスタックし、実際の値をHeapに格納します.従って、Stringの実績値はHeapに格納される.

  • 上の図に示すように、JVMは、Heap上でString Poolを実行します.

  • String Poolは内部でHashMapデータ構造で動作する.Keyは文字列のhashcodeを表し、valueはその文字列の参照アドレスを表します(私はそうだと思います).同じ内容の文字列は同じアドレスを指さなければならないので、このような構造だと思います.

  • したがって、上記の例では、cat 1およびcat 2が参照するアドレスは同じである.次の例では、結果は同じです.
  • public class Main {
        public static void main(String[] args) {
            String cat = "cat";
            catString(cat);
        }
    
        public static void catString(String catArg) {
            System.out.println(catArg == "cat");
        }
    }
    
  • ですが、次の例では機能しません.
  • import java.util.Scanner;
    
    public class Main {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            String cat = "cat";
            String input = sc.next();
    
            System.out.println(cat == input);
        }
    
    }
  • スキャンプログラム入力により実行時に機能する
  • .
    前の
  • に示すように、実行時から文字列までの場合、String Poolによる参照アドレスマッチングは適用されません.
    JVMがString Poolを実行するには、次の手順に従います.
  • .

    3. Application Level Pool


    上で共有したリンクの原文では、Bold CheckはString Constant PoolがApplication-level poolであることを記述している.
    Application-level pool.
  • クラス
  • パッケージ
  • たとえば、Javaアプリケーションレベルで実行されるPoolです.
    すなわち、他のクラスまたは他のパケットの文字列の内容が同じである場合、それらは同じ参照アドレス値を有する.次の例を示します.
    public class Cat {
        String catString;
    
        public Cat(String catString) {
            this.catString = catString;
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            String cat = "cat";
            Cat catClass = new Cat("cat");
    
            System.out.println(cat == catClass.catString);
        }
    
    }

    こつこつ、trueが出力されました!