JAVA和+运算符的字符串类

时间:2015-07-29 10:41:47

标签: java

请检查我的代码并回答,告诉我它在java技术中是如何工作的。

String s1 = "roushan8";
String s2 = "roushan"+8;
String s3 = "roushan"+s1.length();
System.out.println(s1==s2);
System.out.println(s2==s3);
System.out.println(s3==s1);

结果是:

true
false
false

2 个答案:

答案 0 :(得分:5)

==比较参考,而不是状态。因此,如果两个引用都保持完全相同的对象==返回true,则如果保持不同的对象,即使它们的状态相同,它也将返回false。要比较对象的状态,请使用equals方法。

现在区别

String s2 = "roushan"+8;
String s3 = "roushan"+s1.length();

s1.length()不是编译时常量(在编译时它的值是未知的)而8是。

因此,当编译器在编译时知道值时,它可以优化我们的代码,并在编译时连接一次字符串,这意味着

String s2 = "roushan"+8;

将编译为

String s2 = "roushan8";//there is no reason to repeat this concatenation every time at runtime

但是

String s3 = "roushan"+s1.length();
必须在运行时计算

s1.length(),这意味着必须将此代码编译为类似

的内容
String s3 = new StringBuilder("roushan").append(s1.length()).toString();

现在默认情况下,像"roushan8"这样的字符串文字是实例化的(它们最终在字符串文字池中,或者从它们中取出,以避免重新创建相同的字符串两次)。这意味着

String s1 = "roushan8";
String s2 = "roushan8"; // <-- that is how "roushan"+8; will be compiled

将代表字符串池中的同一个实习"roushan8"字面值,由==确认。

但是,使用new String()(而StringBuilder#toString在内部创建new String())在运行时创建的字符串不会被实现。这意味着他们不会尝试使用表示相同文本的文字,但会创建单独的新String实例,因此即使该实例将包含相同的文本,它也将被视为不同的对象,然后是来自String池的文件,由{ {1}}或s1个引用。

您可以通过查看

的字节码来确认这一点
s2

String s1 = "roushan8";
String s2 = "roushan"+8;
String s3 = "roushan"+s1.length();

我们可以看到

正在加载10 0: ldc #19 // String roushan8 2: astore_1 3: ldc #19 // String roushan8 5: astore_2 6: new #21 // class java/lang/StringBuilder 9: dup 10: ldc #23 // String roushan 12: invokespecial #25 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 15: aload_1 16: invokevirtual #28 // Method java/lang/String.length:()I 19: invokevirtual #34 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 22: invokevirtual #38 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 25: astore_3 个字符串 12以后用作"roushan"(构造函数)中的参数
16正在计算StringBuilder <initialization>的下一个值 19并附加到StringBuilder
22现在使用s1.lenbth方法创建表示连接文本的字符串
23并将其存储在StringBuilder#toString变量

答案 1 :(得分:1)

您应该使用s1.equals(s2)==运算符将对象比较为相同(位于内存中的同一地址),因此它不会总是返回true以获得相等的字符串。