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

Java函数参数详解:传值还是传引用?

发布时间:2023-06-13 15:38:45

在Java中,函数参数的传递是按值传递,也就是说将一个变量传递给函数时,实际上传递的是该变量的值,而不是变量本身。但是在一些特殊情况下,这种传递方式也可以看作是传递引用。

为了更好地理解Java中函数参数的传递方式,我们可以先来了解一下Java中的数据类型分类。

Java中的数据类型可以分为基本数据类型和引用数据类型。基本数据类型包括八种:byte、short、int、long、float、double、boolean、char,而引用数据类型包括类、接口、数组等。

传递基本类型参数时,直接传递的是该变量的值,函数内部对该参数的修改不会影响原变量的值,因为它们占用不同的内存空间,并且也没有指向相同内存空间的引用。

而传递引用类型参数时,传递的是该参数所指向的对象的引用(或指针),因此函数内部对该参数所指向对象的修改会影响原来的对象。因为它们实际上指向同一个内存区域。

例如:

public class TestMain {

    public static void main(String[] args) {

        int a = 1;

        System.out.println("before test1 a=" + a);

        test1(a);

        System.out.println("after test1 a=" + a);

        Integer b = new Integer(1);

        System.out.println("before test2 b=" + b);

        test2(b);

        System.out.println("after test2 b=" + b);

    }

    public static void test1(int n) {

        n = n + 1;

        System.out.println("in test1 n=" + n);

    }

    public static void test2(Integer n) {

        n = new Integer(2);

        System.out.println("in test2 n=" + n);

    }

}

执行结果如下:

before test1 a=1

in test1 n=2

after test1 a=1

before test2 b=1

in test2 n=2

after test2 b=1

由此可以看出,在test1函数中,修改n的值不会影响到a的值;而在test2函数中,修改n的值影响的却是b的值。

当我们传递一个对象时,其实传递了该对象的引用,如果在函数内部修改该对象的属性,则该对象的属性被修改了,原始对象也能够感知到属性的更改。例如:

public class TestMain {

    public static void main(String[] args) {

        User user = new User();

        user.name = "Tom";

        System.out.println("before test user name=" + user.name);

        test(user);

        System.out.println("after test user name=" + user.name);

    }

    public static void test(User user) {

        user.name = "Jerry";

        System.out.println("in test user name=" + user.name);

    }

}

class User {

    public String name;

}

执行结果如下:

before test user name=Tom

in test user name=Jerry

after test user name=Jerry

可以看到,当我们调用test函数修改user的name属性之后,原始的user对象的name属性也被修改了。

需要注意的是,如果我们在函数内部重新创建了一个对象并将其赋值给该参数,这个新创建的对象实际上与原始对象没有关系,修改这个对象的属性不会影响到原始对象的属性。例如:

public class TestMain {

    public static void main(String[] args) {

        User user = new User();

        user.name = "Tom";

        System.out.println("before test user name=" + user.name);

        test(user);

        System.out.println("after test user name=" + user.name);

    }

    public static void test(User user) {

        user = new User();

        user.name = "Jerry";

        System.out.println("in test user name=" + user.name);

    }

}

class User {

    public String name;

}

执行结果如下:

before test user name=Tom

in test user name=Jerry

after test user name=Tom

可以看到,在test函数内部将user重新赋值之后,新创建的对象与原始对象没有关系,所以这个修改不会影响原始对象的属性。

综上所述,Java中函数参数的传递方式可以理解为按值传递,对于基本数据类型来说,参数传递的是该变量的值,对于引用类型来说,参数传递的是引用所指向的对象的地址或指针,因此函数内部无法修改传入参数的引用本身,但是可以通过引用去访问修改所指向对象的属性或方法。