0

変数が宣言されて値が割り当てられたときに何が起こるかをJavaソースコードで確認しようとしています。

java.lang.Classでこれを見つけることができませんでした。

特に、

String s1 = "abc";
String s2 = "abc";

文字列は不変であるため、 "s1 == s2"の結果により、これら 2 つの参照 ( s1s2は同じオブジェクトを指しています)

String s2 = "abc";

が発行され、Java は、 既に作成されており、s1が参照しているオブジェクト「abc」の場所を特定し、この場所をs2に割り当てています(?)

これが Java の舞台裏でどのように処理されるかを調べています。

//===========================================

編集:

ここでの Qは、Java がソース コードでこれをどのように処理しているかです。

Java 文字列プールとは何ですか?また、"s" は new String("s") とどう違うのですか? 部分的にこれに答えています。ソースコードでこれをすべて確認しようとしています-それがネイティブのものでない場合.

私はこれが素朴な質問であることを知っていますが、これらの応答を期待していませんでした.

4

3 に答える 3

0

それはJVMに依存します。実装は異なる場合があります。

于 2013-08-02T20:31:02.147 に答える
0

ソースコードでこれをすべて確認しようとしています--それがそれらのネイティブの1つではない場合.

それは可能な限りネイティブであり、「この文字列リテラルをロードする」ためのバイトコード操作を持つ JVM によって処理されます。

次のコードを使用します。

public class StringLiterals {
  public static void main(String[] args) {
    String s = "hello, world";
  }
}

これをコンパイルして実行すると、次のようjavap -c StringLiteralsになります。

Compiled from "StringLiterals.java"
public class StringLiterals extends java.lang.Object{
public StringLiterals();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   ldc #2; //String hello, world
   2:   astore_1
   3:   return

}

2 番目のコード0とは;1に対応するものです。String s = "hello, world"コード0は文字列リテラルに対応します"hello, world"。ファイルにconst #2 をロードするように指示.classし、それが文字列literalであることを示唆していますhello, world。実行javap -c -verbose StringLiteralsすると、ファイルで定義されているすべての const が表示され、.class2 番目の const がその文字列リテラルであることが確認されます。

Compiled from "StringLiterals.java"
public class StringLiterals extends java.lang.Object
  SourceFile: "StringLiterals.java"
  minor version: 0
  major version: 50
  Constant pool:
const #1 = Method   #4.#13; //  java/lang/Object."<init>":()V
const #2 = String   #14;    //  hello, world
const #3 = class    #15;    //  StringLiterals
...

JVM はこれを自由に処理できますが、openjdk はネイティブで処理するため、Java ソースに関連するコードは表示されません。

于 2013-08-02T21:14:07.157 に答える
0

1 つのメンタル モデル:

  1. コンパイル時に、すべての文字列リテラルが「定数テーブル」のクラス定義のバイトコードに書き込まれます。特に文字列インスタンスは、インターンされた文字列プールに格納されます (読み込み中?)。
  2. 実行時に文字列リテラルが参照される場合ldc、インターンされた文字列オブジェクトである定数テーブルからロードされて取得されます。

あなたの例では...

String s1 = "abc";
String s2 = "abc";

次のようになります。

String s1 = ldc #1
String s2 = ldc #1

どこ:

constant #1 = "abc".intern();

java.lang.Class でこれを見つけることができませんでした。

なぜあなたが を見ているのかはわかりませんがjava.lang.Class、どこかで を見ていると思いますがClassLoader、クラスの読み込みでさえ ですnative。ある種の「コード」を見たい場合は、コンパイルされたクラスのバイトコードをjavap. バイトコード命令の読み取りについて説明している古いガイドがあります。ldcString リテラルへのすべての参照は、定数をロードするための命令であることに気付くでしょう。

于 2013-08-02T20:57:20.817 に答える