声明 String a = "helloworld";后发生了什么?

String.java
怎样将helloworld变量赋值给了String类中的value参数的?

    /**
     * Returns {@code true} if, and only if, {@link #length()} is {@code 0}.
     *
     * @return {@code true} if {@link #length()} is {@code 0}, otherwise
     * {@code false}
     *
     * @since 1.6
     */
    public boolean isEmpty() {
        return value.length == 0;
    }

这个value怎样获取到声明的helloworld的?
在什么时候?

阅读 4.2k
4 个回答

前面几位答主都没理解题主的意思。

你一定见过这种Integer a = 1;这个是自动装箱。
https://docs.oracle.com/javas...

而对应String,文档并没有准确提及编译器到底是如何将字符串变成String对象的。
https://docs.oracle.com/javas...

我猜测这也是自动装箱原理。

String a = "helloworld";
相当于
String a = new String({'h','e','l','l','o','w','o','r','l','d'});

"helloworld".isEmpty();
相当于
new String({'h','e','l','l','o','w','o','r','l','d'}).isEmpty();

a 是一个引用,引用到一个 valuehelloworld 的,字符串常量池里的 String 对象

每个方法对应一个栈帧;如下图:
image.png
我们要关注的是操作数栈和局部变量表。
如下:

public class Test {
    void test() {
        String a = "helloworld";
    }
}

在jvm加载Test.class时,就会把‘helloworld’字符串放入常量池中。

我们再看test方法的操作指令:
image.png
ldc:把常量池中字符串的地址放入操作数栈
astore:将操作数栈中的地址数据放到a变量中。

常量池里改为引用了,引用一个string,string 由char[] 构成。在堆中有两个对象,一个是string,另一个是构成string 的 char[]。当调用intern(),就把这个string对象放入常量池。怎么传? 直接给地址值就行了,jvm会把地址值解析为具体对象。可能没get到你到底想问什么?至于你说的"HelloWorld".isEmpty(),这个直接把"HelloWorld" 这个string对象放入操作数栈,调用string.isempty 这个方法,不赋值的话直接就弹出去了。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题