目录
创建String实例的方式:
String 、StringBuilder、StringBuffer对比
两种创建String对象方法的原理对比:
例题1:
String str1 = "abc"; String str2 = "abc"; String str3 = new String("abc"); String str4 = new String("abc"); System.out.println(str1==str2); // true System.out.println(str1==str3); // false System.out.println(str1==str4); // false System.out.println(str3==str4); // false原理如下:
例题2:
class Person{ String name; int age; public Person(String name, int age) { this.name = name; this.age = age; } } Person p1 = new Person("Tom", 12); Person p2 = new Person("Tom", 13); // true System.out.println(p1.name == p2.name);原理:
例题3:
class Person{ String name; int age; public Person(String name, int age) { this.name = name; this.age = age; } } String name1 = new String("Tom"); String name2 = new String("Tom"); Person p1 = new Person(name1, 12); Person p2 = new Person(name2, 13); // false System.out.println(p1.name == p2.name);面试题:
String s = new String("abc")以上方法在内存中创建了几个对象:
两个;一个是对空间中new结构,另一个是char[ ]对应的常量池中的数据:"abc"。
例题4:
String s1 = "Hello"; String s2 = "World"; String s3 = "HelloWorld"; String s4 = "Hello" + "World"; String s5 = s1 + "World"; String s6 = "Hello" + s2; String s7 = s1 + s2; System.out.println(s3==s4); // true System.out.println(s3==s5); // false System.out.println(s3==s6); // false System.out.println(s3==s7); // false System.out.println(s5==s6); // false System.out.println(s5==s7); // false System.out.println(s6==s7); // false String s8 = s5.intern(); System.out.println(s3==s8); // true // s9是常量,常量与常量的运算在常量池中 final String s9 = "Hello"; String s10 = s9 + s2; System.out.println(s10==s3); // true原理:
结论:
常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量只要其中有一个是变量,结果就在对重如果拼接的结果调用intern方法,返回值就在常量池中例题5
public class test03 { String str = new String("good"); char[] ch = {'t', 'e', 's', 't'}; public void change(String str, char ch[]) { str = "test ok"; ch[0] = 'b'; } public static void main(String[] args) { test03 str = new test03(); str.change(str.str, str.ch); System.out.println(str.str); // good System.out.println(str.ch); // best } }1、String :不可变的字符序列,底层使用char[ ]存储
2、StringBuffer:可变的字符序列,线程安全的--效率低;底层使用char[ ]存储
3、StringBuilder:可变的字符序列,jdk5.0新增的,线程不安全的,效率高,底层使用char[ ]存储
源码分析:
String str = new String(); // char[ ] value = new char[0];
String str1 = new String("abc"); // char[ ] value = new char[ ]{'a','b','c'}
StringBuffer sb1 = new StringBuffer(); // char[ ] value = new char[16]; 底层创建了一个长度为16的数组
System.out.println(sb1.length()); // 输出结果为0,因为底层返回的是另一个变量count,而不是直接返回数组value的长度
sb1.append('a'); // value[0] = 'a';
sb1.append('b'); // value[1] = 'b'
StringBuffer sb2 = new StringBuffer("abc"); char[ ] value = new char["abc".length() + 16]
问题1:扩容问题:如果要添加的数据底层数据盛不下,那就需要扩容底层数组,默认情况下,扩容为原来容量的2倍 + 2,同时将原有数据的元素复制到新的数组中
