• java中的参数传递是按引用传递还是按值传递


      最近去面试,有一个面试官问到java中参数传递的问题,感觉自己对于这一块还是理解的不够深。今天我们就一起来学习一下Java中的接口和抽象类。下面是本文的目录大纲:

    一 . 什么是按值传递,什么是按引用传递

    二 . java中的参数传递是按值传递还是按引用传递

    三.总结

    若有不正之处,请多多谅解并欢迎批评指正,不甚感激。

    一 . 什么是按值传递,什么是按引用传递

    按值调用(call by value) : 在参数传递过程中,形参和实参占用了两个完全不同的内存空间。形参所存储的内容是实参存储内容的一份拷贝

    按值传递在基本数据类型数据传递中比较好理解,测试代码如下:

    public class test {
        public static void main(String[] args) {
            int age = 0;
            System.out.println("before change age="+age);
            change(age);
            System.out.println("after change age="+age);
        }
        
        public static void change(int a){
            a=20;
        }
    }

    运行结果:

    before change age=0
    after change age=0

    这个结果相信很多朋友已经猜到:因为在main方法中调用change(age)时,真正传递给change方法的参数只是age的一个副本,所以修改这个副本,并不能修改原来age的值。

    按引用调用:在参数传递的过程中,形参和实参完全是同一块内存空间,两者不分彼此。

    例如:

    main()
    {
     int a=0;
     func(&a);
     printf("%d
    ",a);
    }
    func(int *b)
    {
     *b=10;
    }

    咳咳,这貌似是C语言的按引用传递。java的安引用传递写不出来。

    二. java中的参数传递是按值传递还是按引用传递

    在下结论之前,我们还是看一个例子:

    public class PassByValue {
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
        
        @Override
        public String toString() {
            return "PassByValue [name=" + name + "]";
        }
    
        public static void main(String[] args) {
            PassByValue myDear = new PassByValue();
            myDear.setName("dontKnow");
            String mylove  ="dontKnow";
            int herAge=0;
            System.out.println("myDear name="+myDear.getName());
            System.out.println("myLove ="+mylove);
            System.out.println(herAge);
            stringChange(mylove,myDear,herAge);
            System.out.println("============================================================");
            System.out.println("myDear name="+myDear.getName())
            System.out.println(mylove);
         System.out.println(herAge)
         
    } public static void stringChange(String a,PassByValue b,int age){ a="gaoshan";//这一句相当于a=new String("gaoshan") b.setName("gaoshan");
         age=20; } }

    运行结果如下

    myDear name=dontKnow
    myLove =dontKnow
    0
    ============================================================
    myDear name=gaoshan
    myLove =dontKnow
    0

    我们发现,myDear 中的name 属性通过stringChange()方法改变了,myLove的值并没有改变。

    这里有一个疑问:myDear和mylove 都是引用数据类型,为什么myDear的属性值会改变,而mylove 没有改变呢?

    其实原因在注释中已经说了:在stringChange方法中,a="gaoshan";这一句等价于a=new String("gaoshan"),实际上a作为数据引用发生了改变,指向了一个新的内存地址,而myDear作为数据引用,并没有发生改变,仍然指向main方法中myDear所指向的对象。

    三.总结

    在java中,不存在按引用调用,因为在参数传递过程中,不管传递的是基本数据类型的变量,还是对象的引用,其实都是传递的一个副本。

    在上面的例子中,myDear 所指向的对象之所以会发生改变,是因为在stringChange方法中,通过myDear 的副本b对myDear 所指向的对象进行操作,改变了对象属性,但是

    myDear 本身作为对象引用并没有发生改变。而myLove 没有发生改变是因为在stringChange方法中直接改变了myLove 副本a的值,并没有对myLove 所指向的对象进行修改,所以我们看到 main方法中的myLove所指向的对象并没有发生改变

    本文参考

    java参数传递(超经典):http://blog.sina.com.cn/s/blog_4b622a8e0100c1bo.html

  • 相关阅读:
    Linux systemd & init.d
    windows 气泡提示
    C++17新特性
    Lua & C++
    C++智能指针原理
    C++ Memory Order
    析命令提示符的原理
    设置与获取系统代理信息
    命令查看系统信息
    Linux shell脚本
  • 原文地址:https://www.cnblogs.com/yidaijiankuanzhongbuhui/p/8157562.html
Copyright © 2020-2023  润新知