日期:2014-05-18  浏览次数:20627 次

运行结果你是什么。。
public class MyMain{
public static void main(String[] args) throws Exception {
String a = "s";
StringBuffer b = new StringBuffer("sb"); 
int[] c = {1};
Integer d = new Integer(5);
getRes(a);
getRes(b);
getRes(c);
getRes(d);
System.out.println(a+"--"+b.toString()+"--"+c[0]+"--"+d);
}

public static void getRes(String a)      { a = a+"sssss";}
public static void getRes(StringBuffer b){ b.append("sb");}
public static void getRes(int[] c)       { c[0] = c[0]+1;}
public static void getRes(Integer d)     { d = d+1;}
}

------解决方案--------------------

引用:
Quote: 引用:


元首,java的值传递,你说的我明白了。

public static void getRes(String a) { //这传的是一份地址的拷贝
a = a + "sssss"; //这里a+"ssss"赋值给"a"后,此时的a是一个新对象
}

但是StringBuffer 操作的是同一地址的"内容(sb)",是这样吧
 还没明白,String 指向新对象了,Integer指向新对象了,StringBuffer没有,这个怎么判断,String和Integer对象不可变吗?


其实这个问题应该这样理解public static void getRes(Integer d)     { d = d+1;}
这里 d=d+1,d是一个新的引用,其实里面有se5里面的自动装箱和拆箱,其实真正的源码应该是d=new Integer(d+1);当然d+1也是拆箱,这里其实new了一个新对象,其实就是一个新的引用指向了真正的对象d+1的存储单元,在主程序的d引用其实没有改变,这不同于普通对象的传递,普通对象传入getRes(Entity e),e也是一个不同于主程序里面的另一个引用,但是用set修改属性时,始终指向的是原来的存储单元,所以主程序里面e指向的存储单元改变,值改变
------解决方案--------------------
引用:
Quote: 引用:

[b]
觉得还是从可变类和不可变类的角度来理解更好懂一点,因为是不可变类,所以参加运算时,就新 new 了对象。导致新的结果不能存在之前的内存地址,原来的值依然存在。


“可变类和不可变类”没听过这种定义,是不是把final理解错了
fianl修饰类,只说明类不可被继承。final类的所有方法默认是final的,不可重写,因为类不能继承,就不肯能重写。如String。
fianl修饰变量,表示变量所指向的地址不可修改,即指向的对象不可变。对象里的属性是可变的。
恩 是的 我之前对类前面的final理解不到位,造成了理解的错误。不可变类,一旦创建,变不可再修改其值,所以String Integer等类new出的对象参加运算时,都会生成新的对象,不可修改之前传入的对象值。final 只强调该引用指向的内存地址不可改变,如试图改变final修饰的对象的内存地址,编译报错。