作为形参的sc会生成实参someClass的一个拷贝,但是这个拷贝是someClass在栈空间指向堆空间的地址的拷贝,我们知道,当使用诸如A a = new A();的时候,实际上A a是在栈空间中获得了一个A对象的“引用”,当使用new A();初始化这个对象是,则是在堆空间中申请了空间同时将a指向堆空间中的地址。有了这些知识就不难理解,在方法testRef中通过.的操作其实就是对传进来的实参someClass进行操作,因为此时sc是someClass地址,而若执行了sc = new SomeClass();sc的.的操作变不会再对someClass产生影响,究其原因,是因为此时sc已经指向了堆空间中另一块SomeClass类大小的地址。 简单一点就是说,java在传递参数过程中若参数是对象传递的是对象地址的拷贝,也就是说传递的是地址的值。
这个故事告诉我:凡事不可想当然
补充,今天看sun出的SCJP指南,上面的解释比较科学
可能会问你是否理解传递值到方法中时会发生什么结果。如果方法中的代码改变了变量,对外部的方法是否可见?直接引用 Peter van der Lindens 的 Java 程序员解答的一段话(在 http://www.afu.com) //引用 所有的变量(基本类型值和对象的引用值)都是值传递。但是这不是全部情况,对象是经常通过 Java 的引用变量来操作的。所以也可以说对象是通过引用传递的(引用变量通过值传递) 。这是变量不使用对象的值而是像前一个问题那样描述的使用对象引用的值的结果。最后一行:调用者对基本类型参数(int,char 等)的拷贝在相应参数变化时不会改变。但是,在被调用方法改变相应作为参数传递的对象(引用)字段时,调用者的对象也改变其字段。 //引用结束 如果你来自 C++背景,你可能对值传递参数和用&符号传递引用参数熟悉。在 Java 中没有这样的选择,所有的都是值传递。但是看起来并不总是这样。如果你传递的对象是对象的引用,你不能直接对对象的引用进行操作。 所以如果你操作一个传递到方法的对象的字段, 结果就好像你按引用传递(任何改变结果都会返回到调用函数) 将对象引用作为方法变量 请看下面的例子
java 代码
class ValHold{
publicint i = 10;
}
publicclass ObParm{
publicstaticvoid main(String argv[]){
ObParm o = new ObParm();
o.amethod();
}
publicvoid amethod(){
ValHold v = new ValHold();
v.i=10;
System.out.println("Before another = "+ v.i);
another(v);
System.out.println("After another = "+ v.i);
}//End of amethod
publicvoid another(ValHold v){
v.i = 20;
System.out.println("In another = "+ v.i);
}//End of another
}
程序的输出结果是 Before another = 10 In another = 20 After another = 20 看变量 i 是怎么被修改的。如果 Java 总是值传递(也就是对变量的拷贝) ,它是怎么被修改的呢?过程是这样的方法收到了句柄的拷贝或者对象的引用, 但是这个引用的作用类似于指向真实的指针。对这个字段的改变会反映到它所指的值。这有些像是在 C/C++中指针的自动间接应用的的作用。