String str = "abc";
//在字符串常量池创建了abc
String str1 = new String("abc");
//如果是new一个对象,那么如果字符串常量池没有存在这个对象,那么就创建这个对象,然后在堆中也创建一个,最后指向堆中的对象,如果字符串常量池有了,那么就只在堆中创建,最后也是指向堆中的。
sout(str); //abc
//假设这里的str的地址码为0x2333
str = "abc"+"b";
//先在字符串常量池创建“b“,然后再创建"abcb",最后指向"abcb"。
//这里的str的地址码就改变了,因为 str里面的char[]是被final修饰的,是无法被改变的,所以被赋值的str是指向一个新的地址了
int i= 1;
//假设这里的i的地址码为0x2333
i=i+1;
//i的地址码没有改变还是0x2333
String s = "1";
String s1="2";
String s2 = s+s1;
String s3 = "12";
String s4 ="1"+"2";
String s5 = new String("12");
System.out.println(s2 == s3); //false
System.out.println(s3 == s4); //true
System.out.println(s4 == s5); //false
System.out.println(System.identityHashCode(s2)); //356573597
System.out.println(System.identityHashCode(s3)); //1735600054
System.out.println(System.identityHashCode(s4)); //1735600054
System.out.println(System.identityHashCode(s5)); //21685669
字符串常量池String pool
1.只存放字符串常量
特征:字符串唯一,字符串常量池在堆里,可以被共享,节省了空间,如果没有字符串常量池,那么一改变字符串的值,就要创建三个空间。
2.存放一个字符串:
1)从字符型常量池查找是否存在该字符串空间
2)如果有就直接返回找到的字符串常量对象
3)如果没有就直接创建一个
字符串比较在实际开发中,关注字符串的内容,而不是看它指向哪个空间
= = 比较的是否是同一个对象,比较的是地址
.equals()比较的是内容
string 与stringbuffer
字符串类
String : 不可变的字符串,频繁进行加操作,就会在堆里创建String对象,字符串常量池也会创建,效率低。
所以想对String进行频繁的修改操作,jdk提供了StringBuffer/StringBuilder
StringBuffer是一个线程安全的,所有的方法都加了synchronize关键字,而StingBuilder没有。但是同步方法效率也低。
StringBuilder是线程不安全的,方法都是非同步方法,效率高(单线程可用)
StringBuffer/StringBuilder的操作都是在原有的字符串上进行的,不会创建新的对象,初始的容量为16字符
StringBuffer 方法都返回自己,实现方法的连写,就是.XX().CC().AA().



