← 返回首页
JavaSE系列教程(三十三)
发表时间:2020-01-12 12:59:53
深入了解String类。

今天我们来深入了解下java中使用频率最高的类,String类。

1.String类是final的

String类是 final的,不可被继承。 public final class String。 通过查看String类的源码如下:

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
    ...
}

可见,String类是final的,String的本质是一个字符数组。

2.String内容是不可变的

例如:

String s = "hello";
String temp = s;
s = "Hello";
System.out.println(temp == s); //false, 说明改变字符串内容后,s引用已经指向了新对象。

运行结果:
false

3.静态初始化和动态初始化

静态初始化的字符串在字符串常量池里分配空间。注意:字符串常量池也属于堆内存里一块特殊区域。 动态初始化的字符串永远都是在堆内存中开辟新空间。

例如:

String s1 = "hello";
String s2 = new String("hello");
String s3 = new String("hello");
String s4 = "hello";

System.out.println(s1 == s2);
System.out.println(s2 == s3);
System.out.println(s1 == s4);

运行结果:
false
false
true

4.String类重写了hashCode方法

按理说不同的对象,它们的hashCode应该不同,可是String类重写了hashCode方法,使得字符串内容相同则它们的hashCode也相同。

例如:

String s1 = "hello";
String s2 = new String("hello");
String s3 = new String("hello");

System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println(s3.hashCode());

运行结果:
99162322
99162322
99162322

为了证明这一点,我们可以使用System.identifyHashCode来获得重写之间的hashCode.

String s1 = "hello";
String s2 = new String("hello");
String s3 = new String("hello");

System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println(s3.hashCode());
System.out.println("-----------重写之前的hashCode-----------");
System.out.println(System.identityHashCode(s1));
System.out.println(System.identityHashCode(s2));
System.out.println(System.identityHashCode(s3));

运行结果:
99162322
99162322
99162322
-----------重写之前的hashCode-----------
460141958
1163157884
1956725890

5.使用+拼接字符串

使用+拼接字符串,只要+号两边有任何一个是String变量,其内部都是使用StringBuilder创建了新对象。 +号两边都是字符串字面常量,则在编译阶段会直接解析为拼接后的字面常量,并且在字符串常量池里的寻找该字符串对象是否存在,如果存在则使用字符串常量池里的,如果不存在则创建新对象。

例如:

String s1 = "hello,";
String s2 = "hello,world";
String s3 = s1+"world";
String s4 = "hello,"+"world";
final String s5 = "hello,";
String s6 = s5+"world";
String s7 = new String("hello,world");


System.out.println(s2 == s3);
System.out.println(s2 == s4);
System.out.println(s2 == s6);
System.out.println(s6 == s7);

运行结果:
false
true
true
false

小结:

1)String类是 final的,不可被继承。 public final class String。

2)String是内容不可变的,改变内容就是创建新对象。

3)String分为静态初始化和动态初始化,静态初始化分配在静态常量池,动态初始化分配在堆内存。

4)String类重写了hashCode方法,使得字符串内容相同则hashCode也相同。

5)使用+号拼接字符串通常都是创建新对象,除非+号两边都是字面常量。