JAVA和+运算符的字符串类

rou*_*ngh 2 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);
Run Code Online (Sandbox Code Playgroud)

结果是:

true
false
false
Run Code Online (Sandbox Code Playgroud)

Psh*_*emo 5

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

现在区别

String s2 = "roushan"+8;
String s3 = "roushan"+s1.length();
Run Code Online (Sandbox Code Playgroud)

s1.length()是不是编译时间常量(它的值在编译时不知道)8.

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

String s2 = "roushan"+8;
Run Code Online (Sandbox Code Playgroud)

将编译为

String s2 = "roushan8";//there is no reason to repeat this concatenation every time at runtime
Run Code Online (Sandbox Code Playgroud)

但对于

String s3 = "roushan"+s1.length();
Run Code Online (Sandbox Code Playgroud)

s1.length() 必须在运行时计算,这意味着必须将此代码编译为类似的代码

String s3 = new StringBuilder("roushan").append(s1.length()).toString();
Run Code Online (Sandbox Code Playgroud)

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

String s1 = "roushan8";
String s2 = "roushan8"; // <-- that is how "roushan"+8; will be compiled
Run Code Online (Sandbox Code Playgroud)

将表示"roushan8"来自字符串池的相同实习文字,由其确认==.

但是,通过使用(并在内部创建)在运行时创建的字符串不会被实现.这意味着他们不会试图用文字表示相同的文字,但会创建单独的新的String实例,所以即使该实例将包含相同的文本,它会被当作不同的对象,然后将一个从字符串池,它由存储或引用.new String()StringBuilder#toStringnew String()s1s2


您可以通过查看字节码来确认这一点

String s1 = "roushan8";
String s2 = "roushan"+8;
String s3 = "roushan"+s1.length();
Run Code Online (Sandbox Code Playgroud)

是的

   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
Run Code Online (Sandbox Code Playgroud)

在哪里我们可以看到

"roushan"正在加载10个字符串
12以后用作StringBuilder <initialization>(构造函数)
16中的参数s1.lenbth正在计算的下一个值
19并且
现在使用StringBuilder#toString我们创建的方法附加到StringBuilder 22 表示连接文本的字符串
23并将其存储在s3变量中