值传递的思考
值传递还是引用传递
任何一篇文章都会坚定地回答:值传递
但是,当看到这样一段代码时,也许你会有疑问:
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)的值传递。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/153525.html