前言
首先,我们要认识到一点Java中方法参数的传递都是按值调用的,方法得到的是所有参数值的一个拷贝,它并不能修改传递给它的参数变量的值。下面我们就来详细了解一下,为什么会这么说?
方法参数有两种类型:
- 基础数据类型(数字,布尔值)
- 对象
下面我们分别来分析这两种情况。
基础数据类型
/**
* 方法参数为基础数据类型
*/
public class ParamTest1 {
public static void main(String[] args) {
int number = 10;
changeValue(number);
System.out.println(number);
}
public static void changeValue(int x) {
x = x + 3;
}
}
打印结果为10,并没有发生任何的改变,这是为什么呢?我们来看一下具体的执行流程:
- x被初始化为percent值的一个拷贝
- x + 3 后等于13,但是我们要注意,这里是x等于13,但是percent仍然等于10
- 方法结束之后,x不再使用,而percent的值并没有发生任何改变。
也就是说,一个方法不可能修改一个基本数据类型的参数。
对象
对象引用作为参数的话,是可以修改参数的状态的,但是修改的是这个对象引用的地址值所对应的对象的状态,而不是修改了对象的地址值,也就是说实际上方法参数是对象的话,虽然可以修改参数的状态,但是并没有修改参数的值。
当然,对象引用中又分为两种情况:
修改对象状态
/**
* 方法参数为对象时,修改该对象的状态
*/
public class ParamChangeTest {
public static void main(String[] args) {
User user = new User("Pony马",20000.00);
System.out.println("方法调用前,salary的值为:" + user.getSalary());
tripSalry(user);
System.out.println("方法调用后,salary的值为:" + user.getSalary());
}
public static void tripSalry(User u) {
u.raiseSalary(20);
System.out.println("方法结束,salary的值为: " + u.getSalary());
}
}
class User {
private String name;
private double salary;
public User(String name, double salary) {
this.name = name;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public void raiseSalary(double byPercent) {
double raise = salary * byPercent / 100;
salary += raise;
}
}
打印结果为:
方法调用前,salary的值为:20000.0
方法结束,salary的值为: 24000.0
方法调用后,salary的值为:24000.0
我们来看一下,这个方法调用的过程:
- u被初始化为user值的拷贝,要注意这里的值是user对象所指向内存中的地址的值。
- tripSalary方法应用于这个地址值所指向的对象,也就是说u和user的值指向的内存中的对象的薪水提高了20%(发生了改变)
- 方法结束后,参数变量u不再使用,但是由于这个过程中方法参数的值并没有发生任何改变,仍然指向的是薪水被提高了百分之二十的那个user对象。
对象进行交换
/**
* 方法参数为对象时,进行交换
*/
public class ParamChangeTest {
public static void main(String[] args) {
User user_a = new User("Pony马", 20000.00);
User user_b = new User("Jacky马", 30000.00);
System.out.println("方法调用前,user_a的姓名:" + user_a.getName());
System.out.println("方法调用前,user_b的姓名:" + user_b.getName());
exchange(user_a, user_b);
System.out.println("方法调用后,user_a的姓名:" + user_a.getName());
System.out.println("方法调用后,user_b的姓名:" + user_b.getName());
}
public static void exchange(User a, User b) {
User temp = a;
a = b;
b = temp;
System.out.println("方法结束,a的姓名:" + a.getName());
System.out.println("方法结束,b的姓名:" + b.getName());
}
}
class User {
private String name;
private double salary;
public User(String name, double salary) {
this.name = name;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public void raiseSalary(double byPercent) {
double raise = salary * byPercent / 100;
salary += raise;
}
}
打印结果为:
方法调用前,user_a的姓名:Pony马
方法调用前,user_b的姓名:Jacky马
方法结束,a的姓名:Jacky马
方法结束,b的姓名:Pony马
方法调用后,user_a的姓名:Pony马
方法调用后,user_b的姓名:Jacky马
这里可以看到,方法并没有改变存储在变量user_a和变量user_b中的地址值,exchange方法的参数a和b被初始化为两个地址值的拷贝,这个方法交换的是这两个拷贝,但是在方法结束之后,参数变量a和b被释放掉了,所以原来的变量user_a和user_b仍然引用这个方法之前所引用的对象。
总结
Java中方法参数的使用情况:
- 一个方法不能修改一个基本数据类型的参数
- 一个方法可以改变一个对象参数所指向对象的状态
- 一个方法不能让对象参数引用到别的对象
公众号
扫码或微信搜索Vi的技术博客,关注公众号,不定期送书活动各种福利~