Java的按值传递
来源:互联网 发布:sqlserver 回滚数据 编辑:程序博客网 时间:2024/06/16 22:19
最近在看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,因为它操作的还是那个对象,并没有使用=,相当于放弃原引用。
以上 欢迎指正错误 共同学习
- Java的按值传递
- Java里的按值传递与引用传递
- Java里的按值传递与引用传递
- Java里的按值传递与引用传递
- Java的按值传递和引用传递
- Java:理解Java中函数参数传递的【按值传递】和【按引用传递】
- java的值传递
- Java的值传递
- Java的值传递
- Java的值传递
- JAVA的值传递
- 值传递的Java
- java的值传递还是引用传递
- Java的值传递与引用传递
- Java的值传递和引用传递
- java的值传递与引用传递
- java的引用传递和值传递
- java的引用传递和值传递
- 根据廖雪峰老师的git教程,得出的个人总结
- 数据库连接池性能横向比对(hikari druid c3p0 dbcp jdbc)
- 纯css仿淘宝京东导航菜单栏
- Spring特性
- tensorflow 官方示例
- Java的按值传递
- unity ugui实现整页滑动
- 【linux】--task_struct
- 关于系统调用fork()
- ajax实现文件上传
- Linux下C测试多个*两个const
- 《机器学习实战》学习笔记 --chapter2 K-近邻算法
- STL vector等容器erase操作
- 线程安全与可重入函数