关于别名现象
来源:互联网 发布:java 封装规则 编辑:程序博客网 时间:2024/05/21 22:23
别名现象
转自http://blog.csdn.net/GuLu_GuLu_jp/article/details/49839435
部分自己添加
1 别名现象
假设有一个类,它有两个实例(c1 和 c2),原本c1和c2分别指向两个不同的对象。如果执行c1=c2, 则c1这个引用就会被覆盖,也就是丢失了;而那个不再被引用的对象会由“垃圾回收器”自动清理。这种特殊的现象通常称作“别名现象”。
2.1 别名现象的发生场景
- 对对象进行赋值时
- 方法调用中,传递一个对象时
2.2 对对象进行赋值时的别名现象
- Person.java:很简单的一个类,仅仅拥有一个属性
- Client.java:场景类或测试类
输出如下:
- 分析:
主要关注第三行的输出,可以发现当 p1 的 age 值修改为 18 后,p2 的 age 也变为 18 了,这是为什么?why?
原因是因为,当进行对象赋值操作时,如此处的 p2 = p1; 当该条语句执行完毕,p2 和 p1 将拥有对同一个对象的引用。当对 p1 中的属性进行修改时,因为是相同的对象引用,所以 p2 的值自然也是随之修改了。我们可以类比于C ,在 C 语言中使用指针操作一个内存块,内存块内存储的值被修改了,那么所有指向该内存的指针变量的值都会被修改[注:C语言学的不好]
2.3 方法调用中的别名现象
将一个对象传递给方法时,也会产生别名问题。
- Person.java
- Client.java
输出如下:
- 分析
从输出也可看到,当调用 f() 函数后,即使 f() 函数是 void 类型,但是第2条输出中,person 的值还是改变了。这里我们以为我们给 f() 函数传递了一个值,f() 函数会在其作用域内复制参数 Person person 的副本,然后操作副本。但是实际上我们传递的是一个引用。因此实际改变的是 f() 函数之外的对象。
关于方法中别名现象问题的特别案例:我们知道对于数组对象或Objec类的导出类对象,在将这些对象作为参数传递给方法时,会产生别名现象。但是一个特别要注意的一点就是,别名现象出现的场景!!!只有我们在方法中,直接操作对象的方法来修改该对象的值时,才会产生别名现象。若是在方法内,对该对象重新赋值,即重新 new 一下,那么是不会出现别名现象的。原因待会儿解释,先给出案例。如下:
在 Test.java 中,我们给出了 testArr() 和 testPerson() 方法,分别用于测试数组对象和普通对象在将对象作为参数在方法传递过程中别名现象的情况。我们使用两种情况,一种是直接 new 出一个新对象赋值给形参,然后再执行 testXXX 方法;另一种是直接操作形参,即使用形参的方法直接修改其内的值,然后再执行 testXXX 方法。分别查看两种情况的结果:
① 第一种情况下:
- testArr() 的显示:直接就是 1 2 3 4
- testPerson() 的显示:直接就是 Person [id=1, name=johnnie, age=22, sex=男]
② 第二种情况下:
- testArr() 的显示:直接就是 2 2 3 4
- testPerson() 的显示:直接就是 Person [id=1, name=johnnie, age=21, sex=男]
原因很简单,我们以 changeArr 方法来解释。
在第一种情况下,我们在 changeArr() 中,是使用 new 来改变的,而使用 new 关键字呢,JVM 就会在堆中新开辟一个空间,存储新的数组对象,而 arr 就指向堆中新内存地址的引用。但是,在 changeArr() 中,该 arr 还仅仅是局部变量,其生命周期是和 changeArr() 一样的,与其共存亡的,而我们 changeArr() 方法是没有返回值的,也就是我们没有把 arr 返回,让 testArr() 中的 arr 发生改变,让其重新指向堆中新开辟的内存地址,因此第一种情况是不会发生变化,还是 1 2 3 4。
在第二种情况下,就更容易理解了。因为是直接使用 arr 来修改的,在该片内存空间中直接改变值,所以,即使没有返回值,形参 arr 与 changeArr() 同时挂逼了,外部的 arr 还是指向原来的空间,但是此时该片空间中的数据却已经发生了改变。因此,结果就变为 2 2 3 4 了。
三、综合案例:
一般我们别写程序不会刚刚那样,而是综合起来的。如下:
- Address.java:
- Person.java:
- Client.java:
输出如下:
通过输出,我们可以发现,String 类型的数据操作,并不会出现别名现象。而在操作对象的过程中,别名现象出现了。
四 pdd总结
基本数据类型和string类型数据不会产生别名现象。
阅读全文
0 0
- 关于别名现象
- 别名现象
- 别名现象
- java中的别名现象
- Java中的“别名现象”
- Java笔记---别名现象
- JAVA别名现象
- java 别名现象
- 详述 Java 中的别名现象
- 详述 Java 中的别名现象 .
- java编程思想_005别名现象
- 关于数据类型的别名
- 关于 mysql 别名问题
- 关于效率长尾现象
- [《think in java》学习——操作符]别名现象
- Java中别名现象和对象引用问题
- 由赋值中的“别名现象”引发的思考
- 关于Oracle数据库起别名
- 使用Google Analytics跟踪捕获JavaScript,AngularJS,jQuery的在线错误和异常
- python遇到的问题与解决
- 关于寻路算法的一些思考(4):A* 算法的变体
- [MM] 地牢生成算法@2
- TCP,UDP.HTTP,HTTPS(下)
- 关于别名现象
- 聚类有效性检验(Hubert'Γ )
- 建表语句
- 前端数据结构与算法系列
- Spring boot 中java.util.Date 在json、数据库之间格式的相互转换
- unity3d注意事项
- 关于寻路算法的一些思考(5):处理移动中的障碍物
- springboot添加拦截器
- glob模式