方法-参数传递

方法-参数传递

参数传递:值传递

传递基本数据类型时:把实参的值传递给形参

package com.gcbeen.method;

/**
 * @author gcbeen
 * 
 */
public class HomeWork01 {
    private static int x = 10;

    public static void updataeValue(int value) {
        value = 3 * value;
        System.out.println("value的值:" + value);
    }

    public static void main(String[] args) {
        System.out.println("调用前的值:" + x);
        updataeValue(x);
        System.out.println("调用后的值:" + x);
    }

}



// 调用前的值:10
// value的值:30
// 调用后的值:10

// Process finished with exit code 0

分析

  • 1)value被初始化为x值的一个拷贝(也就是10)
  • 2)value被乘以3后等于30,但注意此时x的值仍为10!
  • 3)这个方法结束后,参数变量value不再使用,被回收。

传递引用数据类型时:把实参引用的值 传递给形参

package com.gcbeen.method;

/**
 * @author gcbeen
 * 
 */
public class User {
    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
  • 执行class
package com.gcbeen.method;

/**
 * @author gcbeen
 * 
 */
public class HomeWork02 {

    public static void updateUser(User student) {
        student.setName("lishen");
        student.setAge(22);
    }

    public static void main(String[] args) {
        User user = new User("zhangsan", 20);
        System.out.println("调用user前的值:" + user.getName() + "," + user.getAge());
        updateUser(user);
        System.out.println("调用user后的值:" + user.getName() + "," + user.getAge());
    }
}
  • 分析一下这个过程:

在这里插入图片描述

分析

  • 1)student 变量被初始化为 user 对象的引用的拷贝。
  • 2)调用student变量的set方法作用在这个引用对象上,user和student同时引用的User对象内部值被修改。
  • 3)方法结束后,student变量不再使用,被释放,而user 变量依然指向User对象。

下面我们通过一个反例来说明

package com.gcbeen.method;

/**
 * @author gcbeen
 * 
 */
public class HomeWork03 {

    /**
     * 交换两个对象
     * @param x
     * @param y
     */
    public static void swap(User x, User y) {
        User temp = x;
        x = y;
        y = temp;
    }

    public static void main(String[] args) {
        User user = new User("user", 26);
        User stu = new User("stu", 18);
        System.out.println("调用前user的值:" + user.getName() + "," + user.getAge());
        System.out.println("调用前stu的值:" + stu.getName() + "," + stu.getAge());
        swap(user, stu);
        System.out.println("调用后user的值:" + user.getName() + "," + user.getAge());
        System.out.println("调用后stu的值:" + stu.getName() + "," + stu.getAge());
    }

}

// 调用前user的值:user,26
// 调用前stu的值:stu,18
// 调用后user的值:user,26
// 调用后stu的值:stu,18

// Process finished with exit code 0
  • 通过程序,会发现user和stu的值并没有发生变化,也就是方法并没有改变存储在变量user和stu中的对象引用。
  • swap方法的参数x和y被初始化为两个对象引用的值的拷贝,这个方法交换的是这两个拷贝的值而已,最终,所做的事都是白费力气罢了。在方法结束后x,y将被丢弃,而原来的变量user和stu仍然引用这个方法调用之前所引用的对象。

在这里插入图片描述

  • 这个过程也充分说明了java程序设计语言对对象采用的不是引用调用,实际上是对象引用进行的是值传递,当然在这里我们可以简单理解为这就是按值调用和引用调用的区别,而且必须明白即使java函数在传递引用数据类型时,也只是拷贝了引用的值罢了,之所以能修改引用数据是因为它们同时指向了一个对象,但这仍然是按值调用而不是引用调用。
  • 总结
    • 一个方法不能修改一个基本数据类型的参数(数值型和布尔型)。
    • 一个方法不能修改一个引用数据类型的参数(引用的值),可以修改一个引用所指向的对象状态,但这仍然是按值调用而非引用调用。
    • 上面两种传递都进行了值拷贝的过程。
posted @ 2022-09-11 11:15  gcbeen  阅读(45)  评论(0)    收藏  举报