Java中值传递的深入思考

值传递还是引用传递

任何一篇文章都会坚定地回答:值传递
但是,当看到这样一段代码时,也许你会有疑问:

	public class TestClass {

    public static void main(String[] args) {
        TargetClass origin = new TargetClass();
        origin.name = "Yan Yu";
        System.out.println(String.format("原本的信息是:%s",origin.name));
        changeAndSayName(origin);
        System.out.println(String.format("现在的信息是:%s",origin.name));
    }

    public static void changeAndSayName(TargetClass obj){
        obj.name = "123";
    }
}

执行结果:

原本的信息是:Yan Yu
现在的信息是:123

哎?不是说好的值传递么?怎么副本传进方法以后,修改字段,原对象的字段也跟着变了?这传进来的难道不是指针吗?

到底什么叫值传递,什么叫引用传递

在搞清楚问题之前,我们有必要严格说明一个问题:
什么叫值传递,什么叫引用传递。
对于Java而言,其实根本就没有什么值传递、引用传递的概念,因为Java就没有指针这个东西,到底是什么传递毫无意义。
只有在和C++/C语言作对比的时候,才有必要说明值传递和引用传递。

如果只从字面意义理解,值传递就是“传递值”,引用传递就是“传递引用”。如果从“无法传递引用,因为Java没有指针”这个角度来理解,Java就确实是值传递,因为没有指针。
但是这没法解释上面那段代码的问题,为什么值变了?

因为Java认为你是把对象的引用当做值传进去了

还是对比C++理解。C++说的引用传递,是在只需要指针的情况下,就可以对某个内存区块进行操作,如果一定要用java的形式写出来,应该是这样:

public class TestClass {

    public static void main(String[] args) {
        TargetClass origin ;
        // 下面一行代码肯定报错,因为java不能取地址
        changeAndSayName(&origin);
        System.out.println(String.format("现在的信息是:%s",origin.name));
    }

    public static void changeAndSayName(TargetClass* obj){
        obj = new TargetClass();
        obj.name = "123";
    }
}

直接对实例操作内存,甚至无需原本的对象初始化
Java能不能做到?做不到。也就是说Java的值传递是相对于直接操作内存而言的。上述例子中实例的值也发生了改变,但从本质上说,你没有操作内存(你没有指针),是JVM操作的。

所以,Java就是值传递,但是是可以影响内存(通过JVM)的值传递。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值