0

I am looking to see in the Java source code what happens when a variable is declared & assigned a value.

I haven't been able to spot this in java.lang.Class.

Particularly, looking to see what happens in

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

String is immutable and thus by the outcome of "s1 == s2", these two references-- s1 and s2 are pointing to the same object and when

String s2 = "abc";

is issued, Java is spotting the location of the object "abc" that already is created and s1 is referring to, and assigning this location to s2 (?)

I am looking to see how this is handled behind the scenes in Java.

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

EDIT:

The Q here is-- how Java is handling this in its source code.

The What is the Java string pool and how is "s" different from new String("s")? is answering this in part. I'm looking to see this all in the source code-- if it's not one of those native.

I know this a naive Q, but didn't expect these responses.

4

3 回答 3

0

我希望在源代码中看到这一切——如果它不是那些原生代码之一。

它几乎是原生的——它由 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

}

第二个代码01对应的是什么String s = "hello, world"; 代码0对应于字符串字面量"hello, world"。它说要在文件中加载 const #2 .class,并暗示它是字符串文字hello, world。如果您运行javap -c -verbose StringLiterals,您将看到.class文件中定义的所有 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

这取决于JVM。实施可能会有所不同。

于 2013-08-02T20:31:02.147 回答
0

一种心理模型:

  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。有一个旧指南在某种程度上解释了阅读字节码指令。您会注意到所有对字符串文字的引用ldc都是用于加载常量的指令。

于 2013-08-02T20:57:20.817 回答