Java的按值传递

    xiaoxiao2021-04-13  23

    最近在看Java传值的问题,觉得醍醐灌顶啊!以前一直认为“对于基本变量类型,Java是按值传递,对于引用类型是按引用传递”,昨天看了些文章,发现自己真是too young too simple!Java中只有按值传递!!!

    来详细解释一下原因。先看基本变量类型的例子:

    //定义了一个改变参数值的函数 public static void changeValue(int x) { x = x *2; } ... ... //调用该函数 int num = 5; System.out.println(num); changeValue(num); System.out.println(num);

    结果还是5,大家都知道对不对。内存机制是这样的: 所以这里是把num存储的5这个值,传递到函数中去,因此函数中的变量值和原来的num是无关的。注意:值传递的精髓是:传递的是存储单元中的内容,而非地址或者引用!

    再看看对象类型的例子:

    class person { public static String name = "Jack"; } //定义一个改变对象属性的方法 public static void changeName(Person p) { p.name = "Rose"; } public static void main(String[] args) { //定义一个Person对象,person是这个对象的引用 Person person = new Person(); //先显示这个对象的name属性 System.out.println(person.name); //调用changeName(Person p)方法 changeName(person); //再显示这个对象的name属性,看是否发生了变化 System.out.println(person.name); }

    第一次输出Jack,第二次输出Rose。好了,你要说“对啊,这就是按引用传递嘛!”注意,在java中,新创建的实体对象在堆内存中开辟空间,而引用变量在栈内存中开辟空间,也就是说,你new的对象是在堆中的,栈中存储的只是改对象在堆中的引用地址。看下面的图: 发现了吗,我们前面说的值传递的定义是传递存储单元中的内容,所以这个时候还是按值传递! 如果在changeName函数中重新new一个对象然后赋值给p呢?这个时候person本身还是不变的,他的过程是:在堆中重新创建一个对象,再把这个对象的引用地址放到p中,这个时候person和p存储的是不同对象的堆地址。

    说到这里,就想说说关于赋值操作,就是这个“=”。赋值操作其实是包含了两个意思:1、放弃了原有的值或引用;2、得到了 = 右侧变量的值或引用。对于基本数据类型变量,= 操作是完整地复制了变量的值。换句话说,“=之后,你我已无关联”。对于非基本数据类型变量,= 操作是复制了变量的引用。参数传递本质就是一种 = 操作。参数是变量,所有我们对变量的操作、变量能有的行为,参数都有。所以把C语言里参数是传值啊、传指针啊的那套理论全忘掉,参数传递就是 = 操作。 所以,像Java的List数据结构这些,在某个方法里面调用add函数这些,改变了原List,因为它操作的还是那个对象,并没有使用=,相当于放弃原引用。


    以上 欢迎指正错误 共同学习

    转载请注明原文地址: https://ju.6miu.com/read-668728.html

    最新回复(0)