1. String s= new String("abc")
创建了两个对象(一个堆(new出来的)里,一个常量池("abc")里),此外还在栈中生成了一个引用s;
这一步其实分了两步,第一步在编译阶段判断常量池中“abc”是否存在,如果存在直接把s指向这个常量的引用,如果没有则在常量池创建对象并将s指向常量的引用;第二步在运行阶段通过new关键字在堆中创建String对象;
2、String a="123";
创建了1个对象
jvm在编译阶段会判断常量池中是否有 "123" 这个常量对象如果有,a直接指向这个常量的引用,如果没有会在常量池里创建这个常量对象。
3、String a="123"+"456";
创建了1个对象
jvm编译阶段过编译器优化后会把字符串常量直接合并成"123456",所有创建对象时最多会在常量池中创建1个对象。
4、String a="123"+new String("456");
创建了4个对象
常量池对象"123" ,"456",new String("456")创建堆对象,还有一个堆对象"123456"。
5.String s=new String("XYZ")+new String("XYZ");
创建了四个对象?
相同的常量池对象"XYZ" ,"456",两次new String("XYZ")创建两个不同的堆对象,还有一个堆对象"XYZXYZ"。
6.String s=new String("123")+new String("XYZ");
创建了五个对象
两个常量池对象"123" ,"XYZ",new String("XYZ")创建的堆对象,new String("123")创建的堆对象,还有一个堆对象"123XYZ"。
String中的 ==符号比较的是 是否是同一个对象,s1和s3都是指常量池“Welcome to Java”,s2这里指向两个对象(堆中的和常量池中的),所以对象不同;
String a = "123";
String b = a + "456";
a是一个引用指向常量池中的"123",a可以被称为常量,然而a+"456"后 b相当于一个引用加上一个常量,所以b是变量;
String 常量存放在常量池中,jvm处于优化考虑,会让内容一致的对象共享内存块,但变量是放在堆空间中的,new 定义的不同变量内存地址不同。
String 常量连接常量,还是常量,依旧用常量池管理,但常量连接变量或者引用就是变量了。
既然能把数组转化为字符串(在上几张有),那也可以将字符串转化为数组(字符串数组):
char[ ] chars="Java".toCharArray(); //调用方法toCharArray来讲“Java”转化为chars【0】=“J”,chars[1]="a"....
在写几个还能把字符串数组转化为字符串的方法:
String s=new String(new char[ ]{"J","a","v","e"});
String s=new String.valueOf(new char[ ]{"J","a","v","e"});
字符和各种数值返回字符串:
String.valueOf(字符和各种数值), 例String.valueOf(2.04),返回的就是'2','0','4'构成的字符串
运行速度:
- StringBuilder > StringBuffer > String
线程安全:
- 线程安全:StringBuffer(内部方法都加上了synchronized,适用多线程,速度略逊StringBuilder) String
- 线程不安全:StringBuilder(适用于单线程)
1.StringBuilder是速度最快的,但是在多线程中不安全,因为内部方法没有synchronized机制保护,所以多只能用于单线程大量数据处理;
2.StringBuffer比StringBuilder速度慢些,因为在内部方法中加了synchronized,但在多线程中是安全的,所以多用于多线程大量数据处理;
3.String用于少量数据处理,String是final类,不能被继承;
StringBuilder和StringBuffer非常擅长于字符串的增删改,倒置等等
为什么用StringBuilder或者StringBuffer进行字符拼接而不用String?
String每次都会创建一个对象,即使改了一点点也会创建一个新的对象,而无用的常量对象多了会导致gc负担;
StringBuilder(JDK5.0 在StringBuffer基础上新增加非线程安全类)和StringBuffer每次结果都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,再改变对象引用;每次通过System.arrayCopy先对维护的char进行扩容,然后再把拼接数据放进去;