1,String底层实现
1)final类型的char数组
private final char value[]; 表明gc回收之前,都是不可变的。
JDK7之前String不可以用在switch表达式中。
2)实现了Comparable接口,字典顺序排序。
image.png
3)重写了equals方法。比较两个char[]数组的元素。
image.png
4)字符串拼接 +
字面值常量拼接:jvm编译器优化,编译期解析为字面值常量。
变量参与拼接:底层调用StringBuffer,最终new一个新的字符串。
image.png
2,StringBuilder和StringBuffer
1)StringBuilder底层
char[] value;可变数组
append操作扩容value数组(底层System.arraycopy),将str copy到新value数组中。
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)
image.png
2)toString时,会new一个新数组。
image.png
3)StringBuffer是通过synchronized 同步的,线程安全的
image.png
image.png
3,JDK8字符串常量池
1)字面值常量
"" 双引号直接声明
,将在常量池中创建常量。
image.png
2)字符串拼接符+变量底层使用StringBuffer new一个String
,在堆中创建对象。
image.png
3)new堆中创建对象,""
常量池中创建常量
image.png
4)jdk8,如果常量池是空的,堆中有对象,则在常量池中创建引用。
image.png
5)jdk6常量池在方法区,StringTable 1009大小。都是字符串常量。
jdk7常量池在堆中,-XX:StringTableSize指定大小。可以存放堆中字符串的引用。
4,String.intern()方法
1)返回和当前字符串equal相同的字符串
该字符串,在常量池中是唯一的。
a string that has the same contents as this string, but is guaranteed to be from a pool of unique strings.
2)str.intern() 当intern方法被调用时,如果常量池已存在当前字符串对象,则直接返回,否则将当前字符串对象加入常量池,返回对象引用。
When the intern method is invoked,if the pool already contains a string equal to this String object as determined by the equals method,then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.
5,例子
public class StringTest {
public static void main(String[] args) {
String s1 = "hello";//字面值方式创建对象:查找字符串常量池(JDK1.8位于堆中),不存在则在池中创建,并返回引用地址。
String s2 = "hello";//字面值方式创建对象:查找字符串常量池,存在,则直接返回引用地址。
//"he"字面值、"llo"字面值
// (JVM编译器对字符串连接符优化)编译期解析为"hello"字面值(需要加入常量池)
// + 如果有变量参与,则底层使用StringBuffer
String s3 = "he" + "llo";
String s4 = new String("he") + new String("llo");
//new创建对象,查找字符串常量池是否存在字面值,不存在则创建,并在堆中再创建一个字符串并返回地址。
String s5 = new String("hello");
System.out.println(s1 == s2);//true
System.out.println(s1 == s3);//true
System.out.println(s1 == s4);//false
System.out.println(s1 == s5);//false
String strA = new String("3") + new String("3");
strA.intern();
String strB = "33";
System.out.println(strA == strB);//true
}
}
网友评论