2011-07-11 30 views
4
class Test{ 
     public static void main(String s[]){ 
       String s1="welcome",s2="come";   
       System.out.println(s1==("wel"+"come")); //prints : true 
       System.out.println(s1==("wel"+s2));  //prints : false 
     } 
} 

我想知道为什么两个println方法都给出不同的结果。 请详细解释。关于java结果的困惑字符串

+0

看看这个主题:http://stackoverflow.com/q/2772763/155137 –

回答

7

==总是比较引用本身。

在第一比较中,恒定字符串表达式"wel" + "come"编译时被评估,所以你最终以相同的参考实习作为用于初始化s1字面。

在第二种情况下,连接在执行时执行,创建一个新的字符串。

要比较两个字符串的内容(而不是检查两个引用是否指向同一个对象)使用equals平等:

System.out.println(s1.equals("wel" + "come")); 
System.out.println(s1.equals("wel" + s2)); 
+0

此外,因为“+”操作是使用StringBuffer或StringBuilder实现的,所以第二个级联作为@Jon解释了哪些不能优化编译时会创建一个新的字符串对象。 – didxga

0

试图通过将其与“比较测试字符串是否相等== “操作员是一件坏事。字符串是对象,所以当使用“==”时,您将比较两个对象的引用,而不是对象本身。

请尝试使用equals()方法。

0

==做对象引用相等性测试。改为使用String.equals()方法(以测试字符串值是否相等)。

s1.equals("wel" + s2); 

您的第二种方法是在运行时测试的。编译器创建新的String对象并将对象引用与新的String对象进行比较。

2
String s1="welcome",s2="come";   
System.out.println(s1==("wel"+"come")); //prints : true 

这些是编译时间常数,所以编译器可以内联代码

System.out.println(s1==("welcome")); //prints : true 

在此,第二部分是不是编译时间常数,所以编译器不能优化,因此,一个新的String对象在运行时创建:

System.out.println(s1==("wel"+s2));  //prints : false 
0

在java中==通过其参考比较的对象,所以,如果两个变量指向同一个对象时,它才会返回true。

在第一种情况下,Java编译器会认识到“wel”+“come”是一个常量,对于s1和“wel”+“come”使用相同的对象(指向常量池的指针)。在第二种情况下,Java编译器不会知道它是一个常量,并且在运行时Java将在执行“wel”+ s2时创建一个新对象,并且比较将失败。

在Java中,应该始终毫不例外地使用.equals方法来比较两个字符串。如果使用==与字符串进行比较,则IDE还应该给出警告。

0

要比较字符串,你应该使用String.equals方法。

0

这是因为编译器解析“WEL” + “来”“欢迎”编译源代码之前(优化它)。表达式可以在编译之前静态解析,编译器也可以。

然后,operator ==在前一种情况下返回true,因为它们都是存储在字符串池中的非常相同的对象“welcome”。

这是一样的,如果你这样做:

0

Java有没有运算符重载,如C++和C#有。所以,这意味着==运营商总是比较参考。和你比较的字符串可能是一样的,但他们有不同的参考。什么原因导致false

但为什么会有真正的结果?那么,Java创建一个字符串池。所有字符串文字将在编译时置入字符串池。这意味着:

String literalString1 = "foo"; 
String literalString2 = "foo"; 
literalString1 == literalString2 // true 

因为它都是对字符串池的引用。

但是,只要您开始构建字符串(使用+),它会在堆上创建新的字符串。然而,Java编译器很聪明,并且在编译时建立了两个String文字。

"wel"+"come" == "welcome" 

由于您正在运行时构建它们。编译器会检测到"wel" + "come"是一个String文字,并将其放入String池中。 "welcome"也是一个字面值,它将搜索字符串池以检查文字是否已经存在于字符串池中。当然它会找到它并使用相同的参考。

0

事实是,在Java中,字符串既可以作为对象也可以作为原始类型处理。

作为一个基本类型:

String text1 = "a";

作为对象:

String text2 = new String("a");

但在Java ==总是比较的引用不值。

当我写这篇文章的代码:

text1 == text2回报false,现在text2 + "b" == "ab"也返回false

,因为它运行时创建对象以恒定的比较,而这正是适用于你的第二个的情况下,在前一种情况下,“wel”+“come”将被java编译器视为“welcome”,并且作为常量,它与您定义字符串变量的常量相同。