欢迎访问宙启技术站
智能推送

Java中函数(Function)的参数传递是按值还是按引用?

发布时间:2023-06-15 09:02:02

在Java中,参数传递既不是按值也不是按引用,而是按值传递的引用。

首先,需要了解Java中的基本数据类型和引用数据类型的区别。基本数据类型包括:byte、short、int、long、float、double、char和boolean,而引用数据类型包括:类、接口、数组、枚举、注解和Lambda表达式等。基本数据类型的值是存储在栈中的,而引用数据类型的值是存储在堆中的对象的引用(地址)。

在Java中,参数传递实际上传递的是变量的副本。当传递一个基本数据类型的变量时,实际上传递的是该变量的值的副本。也就是说,在方法内部修改该变量的值不会影响原始值。示例如下:

public static void main(String[] args) {
    int a = 10;
    add(a);
    System.out.println(a); // 输出10
}

public static void add(int b) {
    b = b + 5;
}

在此示例中,虽然在方法add中对参数b进行了修改,但是原始变量a的值依然是10。因为add方法内部对变量b进行的操作并不会影响原始变量a的值。

当传递一个引用数据类型的变量时,实际上传递的是该变量引用的对象的值的副本。简单理解可以将参数形象地称为一个指针,指向对象在堆中的地址。修改该对象的状态(例如修改对象的属性值)时,其实是对指向该对象的地址进行修改。但改变参数的引用,也就是让参数引用一个新的对象,是不会影响原始变量的引用的。示例如下:

public static void main(String[] args) {
    User user1 = new User("张三");
    updateName(user1);
    System.out.println(user1.getName()); // 输出李四
    
    User user2 = new User("王五");
    updateUser(user2);
    System.out.println(user2.getName()); // 输出赵六
}

public static void updateName(User user) {
    user.setName("李四");
}

public static void updateUser(User user) {
    user = new User("赵六");
}

在此示例中,修改参数user的状态,即调用user.setName("李四"),会改变原始变量user1所引用的对象的状态,因此user1.getName()的值是"李四"。而在调用updateUser方法时,虽然方法内部创建了一个新的对象并让参数user引用了它,但是这并不会改变原始变量user2所引用的对象的引用,因此user2.getName()的值仍然是"王五"。

因此,在Java中,参数传递不是按值也不是按引用,而是按值传递的引用,意味着传递的是变量的副本,但如果变量是引用类型,实际上传递的是该引用变量所引用的对象在堆中的地址的副本。通过参数的副本,我们可以访问同一个对象的不同状态,但是改变参数的引用不会影响原始变量的引用。