Java基础系列(九):方法参数

前言

首先,我们要认识到一点Java中方法参数的传递都是按值调用的,方法得到的是所有参数值的一个拷贝,它并不能修改传递给它的参数变量的值。下面我们就来详细了解一下,为什么会这么说?

方法参数有两种类型:

  1. 基础数据类型(数字,布尔值)
  2. 对象

下面我们分别来分析这两种情况。

基础数据类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
 * 方法参数为基础数据类型
 */
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,并没有发生任何的改变,这是为什么呢?我们来看一下具体的执行流程:

  1. x被初始化为percent值的一个拷贝
  2. x + 3 后等于13,但是我们要注意,这里是x等于13,但是percent仍然等于10
  3. 方法结束之后,x不再使用,而percent的值并没有发生任何改变。

也就是说,一个方法不可能修改一个基本数据类型的参数。

对象

对象引用作为参数的话,是可以修改参数的状态的,但是修改的是这个对象引用的地址值所对应的对象的状态,而不是修改了对象的地址值,也就是说实际上方法参数是对象的话,虽然可以修改参数的状态,但是并没有修改参数的值。 当然,对象引用中又分为两种情况:

修改对象状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/**
 * 方法参数为对象时,修改该对象的状态
 */
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;
    }
}

打印结果为:

1
2
3
方法调用前,salary的值为:20000.0
方法结束,salary的值为: 24000.0
方法调用后,salary的值为:24000.0

我们来看一下,这个方法调用的过程:

  1. u被初始化为user值的拷贝,要注意这里的值是user对象所指向内存中的地址的值。
  2. tripSalary方法应用于这个地址值所指向的对象,也就是说u和user的值指向的内存中的对象的薪水提高了20%(发生了改变)
  3. 方法结束后,参数变量u不再使用,但是由于这个过程中方法参数的值并没有发生任何改变,仍然指向的是薪水被提高了百分之二十的那个user对象。
对象进行交换
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/**
 * 方法参数为对象时,进行交换
 */
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;
    }
}

打印结果为:

1
2
3
4
5
6
方法调用前,user_a的姓名:Pony马
方法调用前,user_b的姓名:Jacky马
方法结束,a的姓名:Jacky马
方法结束,b的姓名:Pony马
方法调用后,user_a的姓名:Pony马
方法调用后,user_b的姓名:Jacky马

这里可以看到,方法并没有改变存储在变量usera和变量userb中的地址值,exchange方法的参数a和b被初始化为两个地址值的拷贝,这个方法交换的是这两个拷贝,但是在方法结束之后,参数变量a和b被释放掉了,所以原来的变量usera和userb仍然引用这个方法之前所引用的对象。

总结

Java中方法参数的使用情况:

  1.  一个方法不能修改一个基本数据类型的参数 
  2.  一个方法可以改变一个对象参数所指向对象的状态
  3.  一个方法不能让对象参数引用到别的对象

 

评论:

3 条评论,访客:3 条,站长:0 条
  1. 浅陌洛城
    浅陌洛城发布于: 

    第一段代码和下面的文章中的percent对不上,建议把代码里面 int number = 10;和相关的number改为percent

  2. Vi的技术博客
    Vi的技术博客发布于: 

    第一段代码中的number变量修改为percent,多谢一楼指正。

发表评论