Fork me on GitHub

String中加号和字符串拼接

字符串常量是编译时确定的,编译完成,生成class文件,那就不会再变了。在编译的时候,编译器会将字符串常量直接放在一起,然后查找常量池里面,有没有对应的字符串。

1
2
3
4
5
6
7
8
9
10
String str1= new String("abc");
String str2= "abc";
String str3= "a"+ "b"+ "c";
System.out.println(str1== str2); //输出false
System.out.println(str1.intern()== str2); //输出true
//intern()方法返回字符串对象的规范化表示形式。
System.out.println(str2== str3); //输出true
String str4= "ab";
String str5= str4+ "c";
System.out.println(str2== str5); //输出false

  • 第一个str1== str2对比的是引用的地址是否相同,由于str1采用的是new String方式定义的,所以地址引用一定不相等。
  • 第二个str1.intern()== str2,当str1调用intern的时候,会检查字符串池中是否含有 该字符串。由于定义的str2已经进入字符串池中,所以会得到相同的引用。
  • 定义str3,在编译的时候,编译器会将字符串常量直接放在一起,然后查找常量池里面,有没有对应的字符串,所以str2和str3是相等的,也就是指向相同的内存区域。
  • 看一下下面的代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    String a = new String("ab");
    String b = new String("ab");
    String c = "ab";
    String d = "a" + "b";
    String e = "b";
    String f = "a" + e;
    System.out.println(b.intern() == a); //输出false
    System.out.println(b.intern() == c); //输出true
    System.out.println(b.intern() == d); //输出true
    System.out.println(b.intern() == f); //输出false
    System.out.println(b.intern() == a.intern()); //输出true

由运行结果可以看出来,b.intern() == a和b.intern() == c可知,采用new 创建的字符串对象不进入字符串池,并且通过b.intern() == d和b.intern() == f可知,字符串相加的时候,都是静态字符串的结果会添加到字符串池,如果其中含有变量(如f中的e)则不会进入字符串池中。但是字符串一旦进入字符串池中,就会先查找池中有无此对象。如果有此对象,则让对象引用指向此对象。如果无此对象,则先创建此对象,再让对象引用指向此对象。

Your support will encourage me to continue to create!