今天我们来深入了解下java中使用频率最高的类,String类。
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的本质是一个字符数组。
例如:
String s = "hello";
String temp = s;
s = "Hello";
System.out.println(temp == s); //false, 说明改变字符串内容后,s引用已经指向了新对象。
运行结果:
false
静态初始化的字符串在字符串常量池里分配空间。注意:字符串常量池也属于堆内存里一块特殊区域。 动态初始化的字符串永远都是在堆内存中开辟新空间。
例如:
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
按理说不同的对象,它们的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
使用+拼接字符串,只要+号两边有任何一个是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)使用+号拼接字符串通常都是创建新对象,除非+号两边都是字面常量。