Java学习笔记之字符串String
String
String
类代表字符串,Java 程序中的所有字符串字面值(如 "abc"
)都作为此类的实例实现。
什么是字符串常量池?
字符串的分配,和其他的对象分配一样,耗费高昂的时间与空间代价。JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化。为 了减少在JVM中创建的字符串的数量,字符串类维护了一个字符串池,每当代码创建字符串常量时,JVM会首先检查字符串常量池。如果字符串已经存在池中, 就返回池中的实例引用。如果字符串不在池中,就会实例化一个字符串并放到池中。
字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享。例如:
1,以下是字符串常量创建String对象
String str = "abc";
字符串String底层是用char来实现的,所以上面的式子等效于:
2,使用new关键字创建String对象
1 char data[] = {'a', 'b', 'c'}; 2 String str = new String(data);
intern()
通过new操作符创建的字符串对象不指向字符串池中 的任何对象,但是可以通过使用字符串的intern()方法来指向其中的某一个。
intern()返回一个保留池字符串,就是一个在全局字符串池中有了一个入口。如果以前没有在全局字符串池中,那么它就会被添加到里面,也就是把对象转化成字符串常量
equals()
通过Object中的equals方法判断两个String内容是否相等
String, StringBuffer,StringBuilder的区别:
- String 字符串内容不可以变
- StringBuffer,StringBuilder 字符串内容可以变
- StringBuilder是线程不安全的,效率高
- StringBuffer是线程安全的,效率低
以下通过一些例子了解String的底层原理
1,下面的代码将创建几个字符串对象
1 String s1 = new String("Hello"); 2 String s2 = new String("Hello");
2,下面的代码输出什么?(关键在intern)
1 String s1 = "abc"; 2 String s2 = new String("abc"); 3 s2.intern(); 4 System.out.println(s1 ==s2);
3,下面的代码输出什么?
1 String s1= "abc"; 2 String s2= "abc"; 3 String s3 = new String("abc"); 4 String s4 = new String("abc"); 5 System.out.println("s3 == s4 : "+(s3==s4)); //false 6 System.out.println("s3.equals(s4) : "+(s3.equals(s4))); //true 7 System.out.println("s1 == s3 : "+(s1==s3)); //false 8 System.out.println("s1.equals(s3) : "+(s1.equals(s3))); //true 9 System.out.println(s1==s2); //true
4,以下不同代码产生不同结果的原因是什么
1 //12、下面的代码输出什么? 2 String str1 = "ab" + "cd"; 3 String str11 = "abcd"; 4 System.out.println("str1 = str11 : "+ (str1 == str11)); //true 5 6 //13、下面的代码输出什么? 7 String str2 = "ab"; 8 String str3 = "cd"; 9 String str4 = str2+str3; 10 String str5 = "abcd"; 11 System.out.println("str4 = str5 : " + (str4==str5)); //false 12 13 //14、下面的代码输出什么? 14 final String str2 = "ab"; 15 final String str3 = "cd"; 16 String str4 = str2+str3; 17 String str5 = "abcd"; 18 System.out.println("str4 = str5 : " + (str4==str5)); //true
存储在常量池中的字符串会先拼接,如果常量池中有拼接后的那个字符串就不会创建新的,如果没有才会创建新的常量
如果+旁边有变量的话,最后会在堆中new一个新的对象,句柄指向那个对象