美文网首页
Java中的值传递和引用传递

Java中的值传递和引用传递

作者: MIRROR1217 | 来源:发表于2021-07-03 18:44 被阅读0次

    一般来说,我们认为Java中传递参数有两种方式, 值传递和引用传递。但是后面又有人认为其实就一种类型,即值传递。那么到底结果是怎样的,我们来分析下。

    实参与形参

    在传递参数过程中,我们会涉及到实参与形参的概念,那么它们是怎样定义的?

    • 形式参数:是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的参数;
    • 实际参数:在调用有参函数时,主调函数和被调函数之间有数据传递关系。在主调函数中调用一个函数时,函数名后面括号中的参数称为“实际参数”。

    举个例子:

    public class App {
        public static void main(String[] args) throws Exception {
            App app = new App();
            app.add(1, 2);
            Person person = new Person("Tome", 18);
            app.printName(person);
        }
    
        // 值传递
        private void add(int x, int y) {// 形参
            System.out.println("x + y =" + (x + y));
        }
    
        // 引用传递
        private void printName(Person person) {// 形参
            System.out.println("name = " + person.name + ",age = " + person.age);
        }
    
        static class Person {
    
            String name;
            int age;
    
            public Person(String name, int age) {
                this.name = name;
                this.age = age;
            }
        }
    }
    

    改变x,y的值,打印结果

    public class App {
        public static void main(String[] args) throws Exception {
            App app = new App();
            int x = 1;
            int y = 2;
            app.add(x, y);
            System.out.println("main::x =" + x + ",y = " + y);
            Person person = new Person("Tome", 18);
            app.printName(person);
        }
    
        // 值传递
        private void add(int x, int y) {// 形参
            x = 3;
            y = 4;
            System.out.println("x =" + x + ",y = " + y);
        }
    
        // 引用传递
        private void printName(Person person) {// 形参
            System.out.println("name = " + person.name + ",age = " + person.age);
        }
    
        static class Person {
    
            String name;
            int age;
    
            public Person(String name, int age) {
                this.name = name;
                this.age = age;
            }
        }
    }
    

    打印结果

    x =3,y = 4
    main::x =1,y = 2
    name = Tome,age = 18
    

    可以看到,在方法内部x,y改变后,原x,y的值不变,这就是我们说的值传递。
    下面我们看下引用传递,示例如下:

    public class App {
        public static void main(String[] args) throws Exception {
            App app = new App();
            int x = 1;
            int y = 2;
            app.add(x, y);
            System.out.println("main::x =" + x + ",y = " + y);
            Person person = new Person("Tome", 18);
            app.printName(person);
            System.out.println("main::name = " + person.name + ",age = " + person.age);
        }
    
        // 值传递
        private void add(int x, int y) {// 形参
            x = 3;
            y = 4;
            System.out.println("x =" + x + ",y = " + y);
        }
    
        // 引用传递
        private void printName(Person person) {// 形参
            person.name = "Jerry";
            person.age = 20;
            System.out.println("name = " + person.name + ",age = " + person.age);
        }
    
        static class Person {
    
            String name;
            int age;
    
            public Person(String name, int age) {
                this.name = name;
                this.age = age;
            }
        }
    }
    

    将Person传入之后改变它内部的值,打印结果如下:

    x =3,y = 4
    main::x =1,y = 2
    name = Jerry,age = 20
    main::name = Jerry,age = 20
    

    结果发现原来的Person也改变,这似乎证明了引用传递的正确性,但是别急,我们在来修改下:

    public class App {
        public static void main(String[] args) throws Exception {
            App app = new App();
            int x = 1;
            int y = 2;
            app.add(x, y);
            System.out.println("main::x =" + x + ",y = " + y);
            Person person = new Person("Tome", 18);
            app.printName(person);
            System.out.println("main::name = " + person.name + ",age = " + person.age);
        }
    
        // 值传递
        private void add(int x, int y) {// 形参
            x = 3;
            y = 4;
            System.out.println("x =" + x + ",y = " + y);
        }
    
        // 引用传递
        private void printName(Person person) {// 形参
            person = new Person();
            person.name = "Jerry";
            person.age = 20;
            System.out.println("name = " + person.name + ",age = " + person.age);
        }
    
        static class Person {
    
            String name;
            int age;
    
            public Person() {
    
            }
    
            public Person(String name, int age) {
                this.name = name;
                this.age = age;
            }
        }
    }
    
    

    我们在方法内部重新new一个新的Person,我们看下打印结果:

    x =3,y = 4
    main::x =1,y = 2
    name = Jerry,age = 20
    main::name = Tome,age = 18
    

    怎么回事,为什么又不一样了?因为第一次其实是把实参对象引用的地址当做值传递给了形式参数。而第二次我们重新构造一个Person,他们指向的地址不一样了,当然不会改变原来对象的值了。

    总结

    所以说,Java中其实还是值传递的,只不过对于对象参数,值的内容是对象的引用。

    相关文章

      网友评论

          本文标题:Java中的值传递和引用传递

          本文链接:https://www.haomeiwen.com/subject/eixpultx.html