我们先来看一段代码
public class Text16 {
public static void main(String[] args) {
Circle demo = new Circle(5);
System.out.println(demo.radius);
change(demo);
System.out.println(demo.radius);
Circle a = new Circle(1);
Circle b = new Circle(2);
method(a,b);
System.out.println("一、a半径:"+a.radius+",b半径:"+b.radius);
}
public static void method(Circle x,Circle y){
Circle tmp = x;
x = y;
y = tmp;
}
public static void change(Circle x)
{
x.radius=0;
}
}
class Circle{
double radius;
Circle(double x){
radius = x;
}
}
结果:
看到这是不是有一点懵逼
因为我们常说除了8大基本类型对象是值传递,其他对象都是引用传递
而在例子中 我们当我们调用
change(Circle x)
方法的时候 确实也改变了原来对象的值,这不就是引用传递吗
但是按照这个推理当我们调用
public static void method(Circle x,Circle y)
的时候,两个对象的值应该交换才对,但是却没有,这是为什么?
这个问题产生的根源是,对于java中参数传递的误区:
8大基本类型对象是值传递,其他对象都是引用传递
其实不然:
java中无论基本类型对象还是其他对象全部都是按照值传递的
这里的“值”可以简单的理解为“对象或原始类型在内存中的地址”(并不准确)。
在调用了
change(Circle x)
但是还没有执行
x.radius=0;
之前,内存是这样的
x.radius=0;
之后,内存是这样的
我们可以这样分析,在调用之后demo把地址赋给x,两者指向同一个内存空间,然后通过x改变的radius的值,demo的值自然也就改变了
同理我们分析调用
public static void method(Circle x,Circle y){
但是没有执行代码之前
内存地址是这样的
然后执行
Circle tmp = x;
x = y;
y = tmp;
之后的内存图
x和y的地址相互交换,但是没有影响到a和b的地址,那么a和b指向的对象自然也就不会改变了
如果看懂了 我们再来看一个例子
Class User{
private String name;
.
.
.
}
public static void foo(User user){
user.setName("Max");// AAA
user = new User("Fifi");// BBB
user.setName("Rowlf");// CCC
}
public static void main(String[] args){
User basicUser = new User("Rover");
foo(basicUser );
}
请问,‘AAA’、‘BBB’、‘CCC’这3行代码执行完后,对象basicUser的name分别是什么?
‘AAA’行:name为‘Max’;
‘BBB’行:name为‘Max’;
‘CCC’行:name为‘Max’;
自己分析
如果对内存空间堆跟栈有不懂的 推荐一下视频讲解
http://study.163.com/course/courseMain.htm?courseId=343001
30课和31课