java到底是引用传递还是值传递?

今天我们来讲讲一个在学习中容易误解的问题,面试中也偶尔问到,java方法调用时到底是值传递还是引用传递?

首先,请大家来做一个判断题,下面的3个问题是否描述正确

1. java基本数据类型传递是值传递,引用数据类型是引用传递

2. java都是引用传递

3. 方法调用时传的是数据值就是指传递,传的是地址就是引用传递

 

我们暂且不直说上面3个问题的正确性,下面,我们通过几个测试案例来测试一下参数传递

1. 基本数据类型当作参数

public class test1 {

    public static void main(String[] args) throws Exception {

        int a = 10;

        change(a);

        System.out.println("a = " + a);

         

    }

    public static void change(int s) {

        s = 20;

        System.out.println("s = " + s);

    }

}

    s = 20 运行结果:  方法执行后,没有改变原有a的值

    a = 10

 

2. 引用类型当作参数

public class Student {
    private String name; //姓名
    Student(String name){
        this.name = name;
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
 
        
}

public class Test1{
    public static void main(String[] args) throws Exception {
      Student s = new Student("haly");
      change(s);
      System.out.println("s = " + s.getName());

  }

    public static void change(Student x) {
         x.setName("wuwu");
         System.out.println("x = " + x.getName());
   }

}

运行结果: 方法执行后,改变了原来s的值

x = wuwu
s = wuwu

 

看到这里,很多同学就觉得问题1答案是正确的, java基本数据类型传递是值传递,引用数据类型是引用传递,但是真的是这样吗?

这里我可以提前透露下答案,上面这个测试之所以改变了原来实参s里面的值,是因为我们传递到方法的都是实参对象的一个拷贝,x对象是s对象引用的一个拷贝,

所以x和s都是指向同一块内存地址,改变x里面的值,相当于改变s的值,因为传的是对象引用的拷贝,而不是对象引用本身,所以是值传递。

如果不好理解,我给大家举个例子:

我有一辆车,我自己有一把车钥匙,有一天我的女朋友想要开车,我就配制了一把车钥匙给她,这时候,相当于方法调用,传递了一把钥匙的拷贝给她。

她在钥匙上刻字,对我的钥匙是没有影响的,但是她拿钥匙打开车,将我的车坐垫换了,我开这辆车的时候,车坐垫的确是换掉了,这是同一个道理。

 

如果还不清楚,我用两张图,分别表示案例1和案例2的值传递:

                            

     案例1                                                                                               案例2

 

 

 如果大家还不好理解,下面我就写一个案例3,让大家更加清晰的看出,java是值传递

 

3. 引用类型当作参数

public class Test1 {
    public static void main(String[] args) throws Exception {
        Student s1 = new Student("小张");
        Student s2 = new Student("小李");
        Test1.swap(s1, s2);
        System.out.println("s1:" + s1.getName() + ",s2:" + s2.getName());

        
    }
    public static void swap(Student x, Student y) {
        Student temp = x;
        x = y;
        y = temp;
        System.out.println("x:" + x.getName() + ",y:" + y.getName());
    }

}

 

运行结果:

x:小李,y:小张
s1:小张,s2:小李

通过测试3的代码,我们可以看出,在方法中交换了两个参数的值,但是原来的值并没有交换,如果是引用传递的话,我们操作的都是实参本身的引用,按理也会交换的。

 

下面,我们通过一个图在仔细思考一下答案:我们交换了x和y对象的引用,对原来的s1和s2并没有影响。

 

 

通过以上代码及图描述,我们可以得出如下2个结论:

1. 如果我们传递的实参是对象引用的拷贝,就是值传递,如果我们传递的实参是引用本身,就是引用传递。

2. 在java中,不管基本数据类型,还是引用类型,都是值传递。

 

 

感谢大家的观看,如有错误之处,欢迎指出,共同学习,共同进步~

如果大家看我的文章觉得有所收获,请将文章分享给你们的朋友,后续我会更新更多浅显,优质的技术文章!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值