函数传参
1.传参方式
函数传递参数的方式有两种
按值传参,函数接收的是调用者提供的值
按引用传参,函数接收到的是调用者提供的变量地址
函数传参流程
那么java是按什么方式传参呢?答案是采用按值传参,函数的形参得到的是实参值的一份拷贝。
2.传递的参数为基本数据类型
1 public class Test {
2 public static void doubleValue(int num) {
3 num = num * 2;
4 }
5
6 public static void main(String[] args) {
7 int x = 1;
8 doubleValue(x);
9 System.out.println(x); //1
10 }
11 }
执行过程
(1)调用函数doubleValue(x)时,num被初始化为x值的一份拷贝,即num=1;
(2)在函数体内,num乘以2以后等于2,但是x还是1;
(3)函数执行结束后,变量num不再使用。
3.传递的参数为引用类型
1 package ja.see.models;
2
3 class Employee {
4 private double salary;
5
6 public Employee(double salary) {
7 this.salary = salary;
8 }
9
10 public double getSalary() {
11 return salary;
12 }
13
14 public void setSalary(double salary) {
15 this.salary = salary;
16 }
17
18 public void doubleSalary(double salary) {
19 this.salary = 2 * salary;
20 }
21 }
22
23 public class Test {
24 public static void increaseSalary(Employee e) {
25 e.doubleSalary(e.getSalary());
26 }
27
28 public static void main(String[] args) {
29 Employee e1 = new Employee(3000.00);
30 System.out.println("After method: " + e1.getSalary());
31 increaseSalary(e1);
32 System.out.println("After method: " + e1.getSalary());
33 }
34 }
执行过程
(1)函数increaseSalary执行时,e被初始化为e1值的拷贝即Employee对象引用的一份拷贝,e与e1引用同一个对象
(2)在函数体内,操作这个对象的引用,e与e1同时引用的对象薪水乘以2
(3)函数执行结束后,变量e不再使用,变量e1继续引用那个薪水被修改为2倍的Employee对象实例
4.举例反证
上面的这个栗子,如果建立在java函数传参是引用传参的观点上也是成立的,所以下面我们来举例证明java函数传参是按值传参。
package com.java.se;
class Employee {
private String name;
public Employee(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Test {
public static void sayName(Employee e) {
e = new Employee("tom");
}
public static void main(String[] args) {
Employee e1 = new Employee("lily");
System.out.println("Before method: " + e1.getName()); //lily
sayName(e1);
System.out.println("After method: " + e1.getName()); //lily
}
}
如果java函数是按引用传参,那么After Method后e1.getName()应该是tom而不是lily;
5.说明
1)在向函数传递对象类型的值时,是将实参对象(e1)的内存地址复制给函数的形参(e),即它们引用的是同一个对象;
2)当函数内部的形参(e)操作这个对象时,外部的实参对象(e1)也会有所体现;
3)但是当将一个新的Employee对象赋值给变量e,同时将其name属性设置为"tom";
如果e1是按引用传递的,那么接下来访问e1.name时应该是"tom",但是结果仍然时"lily";
4)这说明函数内部参数(e)值的修改并不能影响外部实参(e1)的引用;
5)当函数内部参数值(e)修改时,这个参数(e)引用的就是一个局部变量对象了,不再是原先的对象,
6)当函数执行结束时,该局部变量对象会被销毁。
6.总结
(1)一个函数不能修改一个基本数据类型的实参(数值型和布尔型)
(2)一个函数可以改变一个对象实参的状态(但是不能改变一个对象实参的引用)
(3)一个函数不能让一个对象实参去引用一个新的对象