Java到底是值传递还是引用传递【通俗易懂】

我相信很多刚学Java的小伙伴都很难理解Java到底是值传递还是引用传递的问题,但肯定背过这道面试题。确实,Java就是值传递,那什么原理呢?请往下看。

我们先看一段代码:分析一下这两句打印的结果分别是什么。

public class Test {
    public static void main(String[] args) {
        double percent = 10;
        tripleValue(percent);
        System.out.println("percent的值为:" + percent);
    }

    public static void tripleValue(double x){
        x = 3 * x;
        System.out.println("x的值为:" + x);
    }
}
x的值为:30.0
percent的值为:10.0

可能有小伙伴会问了,我明明将变量percent传到tripleValue方法中了,并在方法内,将值乘以了3,那x和percent的值都应该是30.0啊?

嗯,按逻辑讲确实是这样,但Java却不是这么做的,它在你传参的时候,偷偷的将percent变量拷贝了一个“副本”,也就是x,后面再用3 * x的时候,其实乘以的是副本,早就不是你传的percent变量了,等tripleValue方法结束,参数变量x就被干掉了。

那么肯定又有小伙伴问了,你基本数据类型勉强算你过关,那我传个Java对象总能破你的局了吧,我就不信传一个对象地址,你还没影响?

嗯,还真是有影响,但你还破不了我的局,请看如下代码,假如我想将员工的工资提高三倍(如果这个员工是我就好了):

public class Test {
    public static void main(String[] args) {
        Employee e = new Employee(); //创建员工对象
        e.setSalary(10.0); //设置e员工的工资为10
        tripleSalary(e);
        System.out.println("e的工资为:" + e.getSalary());
    }

    public static void tripleSalary(Employee x){
        double addSalary = x.getSalary() * 3; //为员工涨工资
        x.setSalary(addSalary);
        System.out.println("x的工资为:" + x.getSalary());
    }
}
x的工资为:30.0
e的工资为:30.0

从结果上来看,实现方法改变对象参数的状态是完全可以的。理由也很简单,方法得到的是对象引用的“副本”,原来的对象引用和这个副本都引用同一个对象,就类似于这样:

Java到底是值传递还是引用传递【通俗易懂】_第1张图片

在传参的时候,依然搞了一个副本x,但x和e指向的是同一个对象地址,所以x改了,e也改。

我们再通过一个例子来让你完全理解到底是值传递还是引用传递,下面来编写一个交换两个 Employee 对象的方法:

public static void swap(Employee x, Employee y){
	Employee temp = x;
	x = y;
	y = temp;
}

如果 Java 对对象采用的是按引用调用,那么这个方法就应该能够实现交换:

Employee a = new Employee();
Employee b = new Employee();
System.out.println("a的地址值为:" + a);
System.out.println("b的地址值为:" + b);
swap(a, b);
System.out.println("交换后a的地址值为:" + a);
System.out.println("交换后b的地址值为:" + b);
a的地址值为:com.example.test.controller.Employee@5caf905d
b的地址值为:com.example.test.controller.Employee@27716f4
交换后a的地址值为:com.example.test.controller.Employee@5caf905d
交换后b的地址值为:com.example.test.controller.Employee@27716f4

从结果上看出,a和b并没有实现交换,其实原因很简单,在传递参数的过程中,还是拷贝了两个副本,a的副本是x,b的副本是y,方法中交换的也是x和y交换,压根没a和b什么事,所以可以得出结论,Java是值传递。

你可能感兴趣的:(Java知识点,java,开发语言,值传递,引用传递,面试)