Java之String,StringBuilder和StringBuffer

StringBuilder和StringBuffer的char[]可变的,String的char[]是不可变final的。StringBuilder效率高,但是线程不安全;StringBuffer线程安全,但是效率不高。为什么String设计为不可变的,因为线程安全和String实现值传递,而不是引用传递。
Java方法之间传递其实是引用副本的传递:代码如下:
public String change(String s, int i, StringBuffer sb, Person p){
	        s="123"; //改变传递引用副本
	        i=3;
	        sb.append("woshi"); //改变传递值内容
	        p.setAge(100);//改变传递值内容
	        sb = new StringBuffer("sbsb"); //改变传递引用副本
	        p = new Person("bb",44);  //改变传递引用副本
	        return s;
	    }
	 
	    public void testChange(){
	        StringBuffer sb = new StringBuffer("buff");
	        String s = "aaa";
	        int i = 1;
	        Person p = new Person("aa",12);
	        i=2;
	        change(s,i,sb,p);
//	        s="222";
	        System.out.println(s);
	        System.out.println(i);
	        System.out.println(sb.toString());
	        System.out.println(p);
	    }


输出:
aaa
2
buffwoshi
Person [name=aa, age=100]
 从虚拟机角度理解:
这个问题只要站在java虚拟机的角度上就能很好的理解了,很简单的,首先局部变量与方法参数都会存储在棧空间,new 出来的存储在堆空间,当程序执行stringbuffer sb=new stringbuffer(),首先会在棧空间分配一个变量sb(一个引用地址),然后会在堆空间分配一个实实在在的对象,sb指向这个对象,当调用change(stringbuffer sb)方法后,棧空间会copy一份sb的一个引用,也指向堆空间sb这个对象(此时棧空间有俩sb引用变量,并且同时指向同一个对象),执行sb.append(”aa”)后,会更改sb对象内容没问题,当执行sb=new stringbuffer();时copy的那个sb引用会重新指向一个新new出来的对象,方法执行完后棧空间copy的那个sb引用变量消失(如果没有其他引用指向它,它就会等待垃圾回收器的回收),回到主方法后,首次声明的sb引用依然指向原来的sb对象。
部分摘自:https://www.cnblogs.com/woshimrf/p/5263018.html

猜你喜欢

转载自chenghao666.iteye.com/blog/2404609