java存储中的实际参数在哪里

如果我将一个String文字传递给某些metohd:

 String s=new String("stack"); String s2=s.concat("overflow"); 

其中将存储字符串“overflow”。

我的一个朋友争辩说它是在String常量池中创建的,我反对他。

请告诉我

提前致谢。

所有String文字都在常量池中。 结束。 在这种情况下,两个常量"stack""overflow"进入池中。 创建一个新的String ,它保存与池中"stack"相同的值,然后通过将常量池中的"overflow"连接到它来创建另一个String

摘自javap -c -verbose Test

 Constant pool: #1 = Methodref #10.#19 // java/lang/Object."":()V #2 = Class #20 // java/lang/String #3 = String #21 // stack #4 = Methodref #2.#22 // java/lang/String."":(Ljava/lang/String;)V #5 = String #23 // overflow #6 = Methodref #2.#24 // java/lang/String.concat:(Ljava/lang/String;)Ljava/lang/String; 

这个问题肯定是不可判定的,但你可以找到java编译器和JVM的特定组合如何做到这一点。

据我所知,没有任何东西可以阻止编写一个java编译器,当它看到一个字符串常量时, 只要 JLS中有关字符串文字的规则,就会以某种方式发出字节代码以在堆中创建该字符串。仍然保持。 例如, String.intern可以维护一个全局Map,编译器可以编译一个String文字,如下所示:

 create a char array of the desired size put character at index 0 put character at index 1 ... put character at index (length-1) construct the actual string object pass the String just created to String.intern and leave result on the stack 

实际上,可以有一个预处理器将所有字符串常量更改为

 (extra.HeapString.createString(new char[] { ... })) 

并让createString创建一个String实例,使String文字的规则成立。 你无法编写一个程序,可以检测它是从原始源编译还是从预处理源编译(除了通过reflectionextra.HeapString )。

字符串stack将位于堆中,字符串overflow位于常量池中,第三个字符串作为常量池中串联stackoverflow的结果。