关于java String结果的混淆

时间:2011-07-11 09:09:35

标签: java string jdk1.6

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方法都会给出不同的结果。 请详细说明。

9 个答案:

答案 0 :(得分:7)

==总是比较引用本身。

在第一次比较中,常量字符串表达式"wel" + "come"编译时进行评估,因此您最终得到与用于初始化{{1}的文字相同的实习引用。 1}}。

在第二种情况下,连接在执行时执行,创建 new 字符串。

要比较内容相等的两个字符串(而不是检查两个引用是否引用同一个对象),请使用s1

equals

答案 1 :(得分: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

答案 2 :(得分:0)

尝试通过将字符串与“==”运算符进行比较来测试字符串的相等性是一件坏事。字符串是对象,因此在使用“==”时,您要比较两个对象的引用,而不是对象本身。

尝试使用equals()方法。

答案 3 :(得分:0)

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

s1.equals("wel" + s2);

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

答案 4 :(得分:0)

在java ==中,通过引用来比较对象,因此只有当两个变量指向同一个对象时才会返回true。

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

在Java中,应始终毫无例外地使用.equals方法来比较两个字符串。如果对带有==的字符串进行写入比较,您IDE也应该给出警告。

答案 5 :(得分:0)

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

答案 6 :(得分:0)

这是因为编译器在编译之前将“wel”+“come”解析为“welcome” 源代码(优化它)。可以在编译之前静态解析表达式,编译器也可以这样做。

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

就像你这样做:

答案 7 :(得分:0)

Java没有像C ++和C#那样的运算符重载。因此,这意味着==运算符始终比较引用。你比较的字符串可能是相同的,但它们有不同的引用。导致false的原因。

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

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

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

但是一旦你开始构建字符串(使用+),它就会在堆上创建 new 字符串。但是,Java编译器是智能的,并在编译时构建了两个String文字。

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

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

答案 8 :(得分:0)

事实是,在Java中,字符串可以被视为Object或基本类型。

作为原始类型:

String text1 = "a";

作为对象:

String text2 = new String("a");

但在java ==中始终比较引用而不是值。

当我写这段代码时:

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

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