请检查我的代码并回答,告诉我它在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
答案 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
以获得相等的字符串。