Java无法通过形参设置为null改变实参 - Java技术债务


问题描述

在实际业务开发过程中,我们会把实参传递给形参,在方法体内对引用对象进行构建或者修改,从而改变实参,因为对形参对象属性修改时,实参对象也会随着改变,详情请看:Java是值传递还是引用传递?区别是什么? 但是方法的形参对象进行修改设置为null时,发现实参并没有被设置为null,这是为什么呢?

问题例子

class TreeNode{
    int val;
    TreeNode left;
    TreeNode right;

    public TreeNode(int val){
        this.val = val;
        left = null;
        right = null;
    }
}

public class Main{
    public static void setNull(TreeNode node) {
        node = null;
    }

    public static void main(String[] args) {
        TreeNode node = new TreeNode(0);
        System.out.println(node);

        setNull(node);
        System.out.println(node);
    }
}

结果:

TreeNode@ 484
TreeNode@ 484

问题分析

Java无法通过形参设置为null改变实参 - Java技术债务

main函数中的node与setNull函数中的node是栈中两个不同的引用型变量,它们都指向了堆中同一个的TreeNode object。

如图所示,setNull函数仅仅解除了该函数体中的node变量与堆中的TreeNode object的绑定关系,并没有解除main函数中的node与TreeNode object的绑定关系。

Java中的对象是通过引用来传递的,这意味着当我们将一个对象作为参数传递给函数时,实际上是将该对象的引用传递给函数。当在函数内部将该引用设置为null时,只是将引用本身设置为null,而不会对原始对象产生影响。

但是在函数setNull(TreeNode node)中将传入的对象node的成员设置为null,却可以成功。本质上是改变中的TreeNode object中的成员对象node.left的指向,使它指向null。这里并没有改变node.left原先指向的对象。

   登录后才可以发表评论呦...

专注分享Java技术干货,包括
但不仅限于多线程、JVM、Spring Boot
Spring Cloud、 Redis、微服务、
消息队列、Git、面试题 最新动态等。

想交个朋友吗
那就快扫下面吧


微信

Java技术债务

你还可以关注我的公众号

会分享一些干货或者好文章

Java技术债务