java程序设计语言是按值调用还是按引用调用?

前言

在写代码过程中,我们经常会调用方法并且传递参数,参数可能是基本数据类型也可能是对象引用,就像updateHeightAndPrint(int height,Student student)方法这样,height基本数据类型student是对象引用。好像既有按值调用又有按引用调用 (•_•)?

public void updateHeightAndPrint(int height,Student student){
        height+=height;
        System.out.println("Student:"+student.toString());
}
复制代码

真相只有一个

java程序设计语言总是采用按值调用

概念

  1. 按值调用(call by value):表示方法接收的是调用者提供的值。(复制一份数据操作,不会影响到实际参数)
  2. 按引用调用(call by reference):表示方法接收的是调用者提供的变量地址。(直接操作源文件,会影响到实际参数)

注意俩者的区别:按值调用是“参数副本”(基本数据类型传递的是值的拷贝,对象传递的是引用的拷贝,都是拷贝后的副本),按引用调用 直接操作“源文件”。

传递基本数据类型的栗子

public static void main(String[] args) {
        int a = 10;
        int b = 10;
        increaseAndPrint(a,b);
        System.out.println("调用increaseAndPrint()后:a:"+a+",b:"+b);
    }

    /**
     * 增加5并打印输出
     */
    public static void increaseAndPrint(int c,int d){
        c = c + 5 ;
        d = d + 5 ;
        System.out.println("cIncreaseResult:"+c+",dIncreaseResult:"+d);
    }
复制代码

结果为:

image.png

increaseAndPrint()方法调用过后,int a,b的值还是10,可以得出一个方法不可能修改一个基本数据类型的参数。(注意:在调用过程中c被初始化为a值的一个拷贝,d被初始化为b值的一个拷贝,重要的事情多三遍,传递的是值的拷贝、值的拷贝、值的拷贝

传递对象引用的栗子

扫描二维码关注公众号,回复: 14283105 查看本文章
public static void main(String[] args) {
        Student wali = new Student("wali", 170);
        Student jack = new Student("jack", 180);
        increaseHeight(wali,jack);
        System.out.println("wali:"+wali.toString()+",jack:"+jack.toString());
    }

    public static void increaseHeight(Student w,Student j){
        w.setHeight(w.getHeight()+10);
        j.setHeight(j.getHeight()+10);
    }
复制代码

结果:

image.png

可以看到改变一个对象参数状态的方法并不是一件难事。理由很简单,方法得到的是对象引用的拷贝。方法在运行过程中,w为wali对象引用的拷贝,j为jack对象引用的拷贝,也就是说w和wali、j和jack这俩个引用指向的是同一个对象,所以在w.setHeight(w.getHeight()+10)执行后wali对象的height属性变更了,而当方法结束后,w和j都不在使用,当然wali和jack继续引用那个Height被增加了10的对象。

举个反栗阐述,对象引用是按值传递的,也就是说操作的是拷贝,而不是原文件

public static void main(String[] args) {
        Student wali = new Student("wali", 170);
        Student jack = new Student("jack", 180);
        swap(wali,jack);
        System.out.println("交换后wali:"+wali.toString()+",jack:"+jack
                .toString());
    }


    public static void swap(Student w,Student j){
        Student temp=w;
        w=j;
        j=temp;
        System.out.println("swap中:");
        System.out.println("wali:"+w.getName());
        System.out.println("jack:"+j.getName());
    }
复制代码

结果:

image.png

如果java采用的是引用传递那么调用这个方法就应该能够改变wali和jack引用。然后结果并不是我们想象的那样。最终白费力气,在方法结束时w和j被丢弃。原来的变量wali和jack仍然引用方法调用之前所引用的对象。

总结

  • 一个方法不能修改一个基本数据类型的参数(即数值型,或布尔值)
  • 一个方法可以改变一个对象的参数的状态
  • 一个方法不能让对象参数引用一个新的对象。

写在最后

谢谢各位掘友耐心的看到这里,如有错误请多多指教。欢迎在评论区共同探讨问题。感谢!感谢!感谢!

猜你喜欢

转载自juejin.im/post/7109778929912643614