Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java字符串:常量池_Java - Fatal编程技术网

Java字符串:常量池

Java字符串:常量池,java,Java,可能重复: 输出: EQUAL:true//已理解字符串池中的相同字符串引用 十, 十, EQUAL:false//为什么 String s4 = "length: " + s3.length(); 创建新的字符串对象 因此,s3引用不同的对象,s4引用不同的对象,这使得==条件返回false 没有“新”操作员。所以一切都必须在常量池中创建,而常量池不能有重复的值 与 String s4 = new StringBuilder().append("length: ")

可能重复:

输出:

EQUAL:true//已理解字符串池中的相同字符串引用

十,

十,

EQUAL:false//为什么

 String s4 = "length: " + s3.length();
创建新的字符串对象

因此,s3引用不同的对象,s4引用不同的对象,这使得
==
条件返回
false


没有“新”操作员。所以一切都必须在常量池中创建,而常量池不能有重复的值

String s4 = new StringBuilder().append("length: ")
                               .append(Integer.toString(s3.length()))
                               .toString();
因此它创建了许多新对象和一个新字符串。

对象(和数组)上的“==”是物理相等。也就是说,对于对象a和b,如果a和b指向同一对象,则a==b为真

编译器会为您进行一些优化。例如,字符串“length”作为常量仅存储一次。因此,s1和s2指向相同的(常量)字符串

也许看看输出的字节码会有所帮助。请注意,这是从非标准java编译器生成的jasmin汇编代码。您可以通过运行“javap-c”来确认java编译器做了类似的事情(尽管输出可读性较差)


将引用加载到常量字符串“length”并存储在s1中

ldc "length"
astore_1
加载对(相同)常量字符串“length”的引用并存储在s2中

ldc "length"
astore_2
比较并打印结果。它不太可读

getstatic java/lang/System/out Ljava/io/PrintStream;
new java/lang/StringBuffer
dup
invokespecial java/lang/StringBuffer/<init>()V
ldc "EQUAL: "
invokevirtual java/lang/StringBuffer/append(Ljava/lang/String;)Ljava/lang/StringBuffer;
aload_1
aload_2
if_acmpeq true0
iconst_0
goto end1
true0:
iconst_1
end1:
invokevirtual java/lang/StringBuffer/append(Z)Ljava/lang/StringBuffer;
invokevirtual java/lang/StringBuffer/toString()Ljava/lang/String;
invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
将“长度:”与长度串联并存储在s4中。请注意,连接将创建一个新字符串(从而创建一个新引用)

newjava/lang/StringBuffer
重复
调用特殊的java/lang/StringBuffer/()V
最不发达国家“长度”:
调用虚拟java/lang/StringBuffer/append(Ljava/lang/String;)Ljava/lang/StringBuffer;
阿洛德3
invokeVirtualJava/lang/String/length()I
invokevirtualjava/lang/StringBuffer/append(I)Ljava/lang/StringBuffer;
InvokeVirtualJava/lang/StringBuffer/toString()Ljava/lang/String;
阿斯托尔4号
像以前一样打印并返回


如您所见,前两个变量引用“常量池”中的相同字符串。变量s3也指常量池中的字符串,但s4指的是由常量字符串和数字构建的新字符串


顺便说一句,你不应该依赖这种行为

@minitech错了。这是一个重复的一个重复的一个重复的一个(…)你可能想通过你的一些其他问题,看看你是否可以接受一些其他的答案。你的接受是我们回答你问题的方式,而你只花了20美分。正是这样的问题让我相信Java设计人员最大的错误是没有为字符串添加默认的
==
操作符。@dasblinkenlight是的,或者直接使用“无指针算术”的思想和摆脱==对引用。一个本机
布尔系统。sameObject(对象o1,对象o2)
会很好。@dasblinkenlight:当然。我想知道他们的理由是什么。嗯,通过语法巫术对字符串的整个处理很笨拙。没有“新”运算符。所以所有内容都必须在常量池中创建,不能有重复的值?+1编译器简化了comp中已知的字符串ile时间。
s3.length()
不是一个方法调用,编译器在编译时优化/知道其结果。@Dhananjay:正如Peter Lawrey所解释的,s3.length()在编译时无法计算出来,它在运行时进行计算并创建新的字符串对象。
ldc "length"
astore_2
getstatic java/lang/System/out Ljava/io/PrintStream;
new java/lang/StringBuffer
dup
invokespecial java/lang/StringBuffer/<init>()V
ldc "EQUAL: "
invokevirtual java/lang/StringBuffer/append(Ljava/lang/String;)Ljava/lang/StringBuffer;
aload_1
aload_2
if_acmpeq true0
iconst_0
goto end1
true0:
iconst_1
end1:
invokevirtual java/lang/StringBuffer/append(Z)Ljava/lang/StringBuffer;
invokevirtual java/lang/StringBuffer/toString()Ljava/lang/String;
invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
ldc "length: 10"
astore_3
new java/lang/StringBuffer
dup
invokespecial java/lang/StringBuffer/<init>()V
ldc "length: "
invokevirtual java/lang/StringBuffer/append(Ljava/lang/String;)Ljava/lang/StringBuffer;
aload_3
invokevirtual java/lang/String/length()I
invokevirtual java/lang/StringBuffer/append(I)Ljava/lang/StringBuffer;
invokevirtual java/lang/StringBuffer/toString()Ljava/lang/String;
astore 4