问题1
String a1 = "I Love" + " Java";
String a2 = "I Love " + "Java";
System.out.println( a1 == a2 ); // true
String b1 = "I Love";
b1 += " Java";
String b2 = "I Love ";
b2 += "Java";
System.out.println( b1 == b2 ); // false
在第一种情况下,我理解它是两个字符串文字的串联,所以结果"我喜欢Java"将被实习,结果如实。但是,我不确定第二种情况。
问题2
String a1 = "I Love" + " Java"; // line 1
String a2 = "I Love " + "Java"; // line 2
String b1 = "I Love";
b1 += " Java";
String b2 = "I Love ";
b2 += "Java";
String b3 = b1.intern();
System.out.println( b1 == b3 ); // false
以上返回false,但如果我注释掉第1行和第2行,则返回true。那是为什么?
答案 0 :(得分:6)
问题的第一部分很简单:Java编译器将多个字符串文字的连接视为单个字符串文字,即
"I Love" + " Java"
和
"I Love Java"
是两个相同的字符串文字,可以正确实习。
相同的实习行为不适用于字符串的+=
操作,因此b1
和b2
实际上是在运行时构建的。
第二部分比较棘手。回想一下,b1.intern()
可能会返回b1
或与其相等的其他String
个对象。当您保留a1
和a2
时,您会从a1
的电话回复b1.intern()
。当您注释掉a1
和a2
时,不会返回现有副本,因此b1.intern()
会自动返回b1
。
答案 1 :(得分:1)
来自实习生()docs
所有文字字符串和字符串值常量表达式都是实体。字符串文字在The Java™Language Specification。的第3.10.5节中定义。
- 由常量表达式计算的字符串(第15.28节)计算在 编译时间,然后将其视为文字。
- 在运行时通过串联计算的字符串是新创建的 因此不同。
你的字符串b1实际上没有实习。因此存在差异。
答案 2 :(得分:0)
回答问题1:
您无法将两个字符串与==
进行比较。 ==
比较两种原始数据类型(int,long,float,double和boolean)或object references 。这意味着如果参考变量(a1,a2,b1,b2)没有相同的引用(意味着它们不指向内存中的同一个对象),则它们不相等(与{{1比较) }})。
如果要与==
进行比较,表达式将为真,因为对象的数据是相同的。
在第一种情况下,Java足够聪明,可以在为它们分配一些内存(甚至在编译之前)之前连接字符串,这意味着两个字符串都存储在同一个地址中。因此,变量a1和a2引用相同的对象并且相等(b1.equals(b2)
)。
在第二种情况下,首先为变量分配不同的值(与第一种情况不同)。这意味着他们在内存中获得了一个单独的地址。即使您更改了值以使它们相同,地址也不会更改,并且与==
的比较评估为false。这在运行时发生。
关于问题2:@dasblinkenlight已经给出了一个很好的答案。