关于java值传递跟引用传递的常见误区

我们先来看一段代码


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){
   
   

但是没有执行代码之前

内存地址是这样的



a把地址传给x  b把地址传给y  a和x指向同一个对象  b和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课




猜你喜欢

转载自blog.csdn.net/a447332241/article/details/78939962
今日推荐