String的不变模式:
对于基本数据类型String而言,它的实例可以在运行期间保持状态永远不会被改变
1.不变模式:
一个字符串对象创建后,他的值不会被改变
String str1="hello";//创建了一个对象 他的值永远不会改变
System.out.println(str1);
str1+=" world!";//两个字符串对象粘粘,系统其实创建了一个新的对象,把Str1的指向改了,指向新的对象;hello就 //变成了垃圾;
System.out.println(str1);
//如果一直这样创建会影响系统的效率;要频繁的改变字符串对象的值就用StringBuffer来描述;
StringBuffer sb=new StringBuffer("[");
sb.append("hehe");
sb.append("]");//append();不会制造垃圾,真正在改sb的值;
System.out.println(sb);
二、对象池
Object obj = new Object();
obj是对象的引用,它位于栈中, new Object() 才是对象,它位于堆中。(对象入堆,变量入栈)
可以这样理解obj是拴在气球上的绳子,new Object() 是气球,我们通过对象的引用访问对象,就像我们那着绳子气球才不会跑掉。
创建String 的方式有两种:
1, String str=new String("abc");
2, String s="def";
虽然两种方法返回的都是String对象的一个引用,但是java虚拟机jvm对这两种对象的处理的方式不同,对于第一种
jvm会立即在heap中创建一个对象,然后返回这个对象的引用给客户;对于第二种,jvm会首先在String对象池中通过
String的equals方法查找是对象池中是否存放该String对象,如果有则会返回已有的对象的引用给客户而不是在heap
中创建一个新的对象,如果对象池中没有该String对象, jvm就会在heap中创建一个新的对象,将他的引用返回给客
户 ,同时将这个引用添加到String pool中、
使用第一种方法创建的对象,jvm不会将String对象放进对象池中,除非调用String 的intern方法
package learn;
public class AutoBox {
public static void main(String[] args) {
Integer integer=12;
System.out.println(integer+13);
Integer i1=13;
Integer i2=13;
Integer i3=137;
Integer i4=137;
System.out.println(i1==i2);
test();
}
public static void test(){
String str=new String("abc");//jvm在堆上创建一个对象
//jvm在String pool中找不到值为'abc‘的字符串,因此在堆上创建一个String对象,并将这个对象
//存放到String pool中,此时堆上有两个String对象
String s="abc";
if(str==s){
System.out.println("str==s");
}else{
System.out.println("not");
}
String s3="abc";
//这个时候,jvm发现String pool中已经存在值为“abc"的字符串,因此直接返回s 的引用给 s3
//也就是说s和s3指向同一个对象
if(s==s3){
System.out.println("s==s3");
}else{
System.out.println("s!=s3");
}
}
}
也就是说,对于一个字符串,任何操作返回的对象都是一个新的对象,而不是字符串的本身