2017-07-18 80 views
3

问题1的java字符串连接和实习

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。这是为什么?

+2

我们从来没有真正比较使用==操作符串并使用.equals方法,而不是 –

+1

@JoeyPinto OP使用''==了解Java的内部,发现行为看起来很奇怪,但有一个合理的解释。 – dasblinkenlight

回答

4

你问题的第一部分是简单的:Java编译器会将多个字符串文字的串联为一个字符串字面量,即

"I Love" + " Java" 

"I Love Java" 

两个相同的字符串文字,得到适当的实习。

同样的实习行为确实适用于+=操作的字符串,所以b1b2在运行时实际构建。

第二部分更棘手。回想一下,b1.intern()可能会返回b1或与其等效的某个其他String对象。当您保留a1a2时,您将a1拨回b1.intern()。当您注释掉a1a2时,没有现有的副本可以返回,因此b1.intern()本身可让您返回b1

+0

我想我现在明白了。谢谢@dasblinkenlight! – wli75

1

从实习生()文档

所有文字字符串和字符串值常量表达式拘留。字符串文字在Java™语言规范的第3.10.5节中定义。

而且从JLS 3.10.5

  • 字符串由常量表达式(§15.28)来计算在 编译时被计算并然后进行处理,好像他们是文字。
    • 在运行时通过串联计算的字符串是新创建的,因此它们是不同的。

你串B1实际上没有拘留。因此有所不同。

+0

感谢您指点我的相关文档! – wli75

0

回答问题1:

你不能==比较两个字符串。==比较两个原始数据类型(int,long,float,double和boolean)或对象引用。这意味着如果参考变量(a1,a2,b1,b2)不具有相同的参考(意味着它们不指向存储器中的同一个对象),则不等于(与==比较)。

如果您将与b1.equals(b2)进行比较,则表达式为真,因为对象的数据是相同的。

在第一种情况下,Java在将字符串分配给某些内存之前(甚至在编译之前)就足够聪明,这意味着两个字符串都存储在相同的地址。因此,变量a1和a2引用相同的对象并且相等(==)。

在第二种情况下,您首先为变量赋予不同的值(与第一种情况不同)。这意味着他们在内存中获得一个单独的地址。即使您更改值以使它们相同,地址也不会更改,并且与==的比较计算结果为false。这在运行时发生。

至于问题2:@dasblinkenlight已经给出了很好的答案。