• Java是值传递还是引用传递


    前言

    许久未曾写文了,今天决定水一篇

    ——南方

    证明

    形参/实参

    • 形参:用于定义函数/方法,接收实参,不需要有确定的值
    • 实参:用于传递给函数/方法的参数,必须有确定的值
    public static void main(String[] args) {
            String a = "b";
            //这里的a就是实参
            print(a);
        }
    
        //这里的s参数就是形参
        public static void print(String s){
            System.out.println(s);
        }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    值传递/引用传递

    • 值传递 :方法接收的是实参值的拷贝,会创建副本
    • 引用传递 :方法接收的直接是实参所引用的对象在堆中的地址,不会创建副本

    证明过程

    使用基本类型参数

        public static void main(String[] args) {
            String a = "a";
            String b = "b";
            print(a, b);
            System.out.println("a:" + a); //a:a
            System.out.println("b:" + b); //b:b
        }
    
        public static void print(String c, String d) {
            String e = c;
            c = d;
            d = e;
            System.out.println("c:" + c); //c:b
            System.out.println("d:" + d); //d:a
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    上述代码很简单,结果呢,很明确,经过print()方法的执行,丝毫未影响到 a,b本身的值,因为c,d的值只是从a,b那里复制过来的,原来的还是原来的,复制品的修改不影响原品的数据

    使用引用类型

    public class Dog {
        String name;
    
        Dog(String name) {
            this.name = name;
        }
    
        String getName() {
            return this.name;
        }
    
        void setName(String name) {
            this.name = name;
        }
    
        String getObjectAddress() {
            return super.toString();
        }
    }
    
    
    public static void main(String[] args) {
    	Dog dog = new Dog("A");
    	System.out.println(dog.getObjectAddress()); //Dog@15db9742
    	func(dog);
    	System.out.println(dog.getObjectAddress()); //Dog@15db9742
    	System.out.println(dog.getName()); // B
    }
    private static void func(Dog dog) {
    	System.out.println(dog.getObjectAddress());//Dog@15db9742
    	dog.setName("B");
    	System.out.println(dog.getObjectAddress());//Dog@15db9742
    }
    
    • 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

    此时就会有很多人疑惑了,为啥在这里值发生了改变,其实原因很简单,它们是引用的同一个对象

    再次证明

    public class Dog {
        String name;
    
        Dog(String name) {
            this.name = name;
        }
    
        String getName() {
            return this.name;
        }
    
        void setName(String name) {
            this.name = name;
        }
    
        String getObjectAddress() {
            return super.toString();
        }
    }
    
    
    public static void main(String[] args) {
            Dog dog = new Dog("A");
            System.out.println(dog.getObjectAddress()); // Dog@15db9742
            func(dog);
            System.out.println(dog.getObjectAddress()); // Dog@15db9742
            System.out.println(dog.getName()); // A
        }
        private static void func(Dog dog) {
            System.out.println(dog.getObjectAddress()); // Dog@15db9742
            dog = new Dog("B");
            System.out.println(dog.getObjectAddress()); // Dog@6d06d69c
            System.out.println(dog.getName()); // B
        }
    
    • 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

    在上面⽅法中将指针引⽤了其它对象,那么此时⽅法⾥和⽅法外的两个指针指向了不同的对象,在⼀个 指针改变其所指向对象的内容对另⼀个指针所指向的对象没有影响

    总结

    Java 中将实参传递给方法的方式是:值传递

    • 如果参数是基本类型的话,传递的就是基本类型的字面量值的拷贝
    • 如果参数是引用类型,传递的就是实参所引用的对象在堆中地址值的拷贝
  • 相关阅读:
    Spring是什么?
    Vue生命周期与自定义指令
    【Logback+Spring-Aop】实现全面生态化的全链路日志追踪系统服务插件「Logback-MDC篇」
    Java 下数据业务逻辑开发技术 JOOQ 和 SPL
    vue-router的安装和使用
    golang学习笔记——select 判断语句
    liteos-M 编译链接问题记录及对应解决方案
    three.js 3D Banner实战
    Kotlin笔记(四):高阶函数
    计算机开题报告怎么写?开题报告的几大模块!研究内容、研究方法、工作安排、预期目的
  • 原文地址:https://blog.csdn.net/wzp12321/article/details/125880861