参数传递问题

首先要明确,在程序设计语言中,将参数传递给方法(函数)的方式有两种

  • 值传递表示方法接收的是调用者提供的值
  • 引用传递表示方法接收的是调用者提供的地址(引用可以理解为地址)

一个方法可以修改传递引用所对应的变量值,而不能修改传递值所对应的变量值!因为值传递实际上是对值进行拷贝后再传递,不会影响原来的值。

两个重要理解误区:

误区一、值传递和引用传递,区分的条件是传递的内容,如果是个值,就是值传递。如果是个引用,就是引用传递。

误区二、传递的参数如果是基本数据类型,那就是值传递,如果是对象,那就是引用传递。

带着这两个误区往下看,在java中参数是如何进行传递的呢?

这里先说结论避免混淆:

java语言中都是采用值传递的方式!

java中的参数类型分为两种:基本数据类型对象引用。下面我们分别看看他们是如何传递的。

1.基本数据类型

eg1.

public static void tripleValue(double x){
    x=3*x;
}

@Test
double percent=10;
tripleValue(10);
//调用这个方法后,percent的值仍然为10!

具体执行流程如下:

(1) x被初始化为percent值的一个拷贝(也就是10)

(2) x被乘以3后等于30,但是percent仍然为10

(3) 这个方法结束后,参数变量x不再使用

2.对象引用

eg2.

class Employee{
	double salary;
}

public static void tripleValue(Employee x){
	x.salary=3*x.salary;
}

@Test
harry=new Employee(..);
tripleValue(harry);
//执行过后,harry中的salary值变为了原来的三倍!

具体执行流程如下:

(1) harry的值是一个对象的引用,x被初始化为harry值的拷贝,也是该对象的引用

(2) tripleValue方法应用于这个对象引用。x和harry同时引用的那个Employee对象的salary值变为原来三倍。

(3) 方法结束后,参数变量x不再使用,但harry依然引用该对象。

java 传值和传参区别 java传值还是传引用_值传递

3.一个更直观的例子

//一个交换两个雇员对象的方法
public static void swap(Employee x,Employee y){
    Employee temp=x;
    x=y;
    y=temp;
}

@Test
Employee a=new Employee("Alice"...);
Employee b=new Employee("Bob"...);
swap(a,b);
//如果是按引用传递的话,那么交换后a中的数据应该是"Bob",b中的数据应该是"Alice",但实际上并不是这样的!

实际上,swap方法的参数x和y被初始化为两个对象引用的拷贝,在这个方法中交换的是这两个拷贝。在方法结束时,参数变量x和y被丢弃了,原来的变量a和b仍然引用这个方法调用之前所引用的对象。

java 传值和传参区别 java传值还是传引用_java_02

所以在java中,无论是对象引用还是基本数据类型,都是按照值传递的!

4.总结

值传递和引用传递根本区别

  • 值传递:会创建副本(Copy),操作是在副本上进行的,不会改变原始数据(实参)。
  • 引用传递:不创建副本,操作时在原始数据上完成的。

假设现在有一把钥匙和一个对应的房间(对象),我们需要把钥匙给别人。

a.我们将钥匙新配了一把再交给别人,那就是值传递

b.我们直接将钥匙交给别人,那就是引用传递

无论是值传递还是引用传递,我们都可以对房间(对象)进行操作(eg2.),但是值传递不会改变原来数据(钥匙)。