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
的结果。