小实验、小思考(一)------List添加对象引发的小思考

来源:互联网 发布:手机视频剪辑拼接软件 编辑:程序博客网 时间:2024/05/01 01:05
工作一年,一直在做应用,现在晚上终于偷点闲,可以多看看基础了,做做小实验,回顾一下基础,重走一遍学习JAVA的道路,温故而知新。
废话不多说,上代码。
代码 1

结果:
显然,实例的值改变了,存到内存中的值也同样被改变。这也就是我们看到所有实例的值都是最后一次的值的原因。那么?这是否意味着list中存入相同的实例,也会被认为是两个呢? 继续试验:
代码2:

结果:

显然,是可以添加的,也就是说 arrayList的size是和添加次数有关的,并不覆盖。他不检查是否相同重复。那么,在List中取出值进行修改,外面的值会改变么,改完之后是否还需要添加进去呢?继续试验:
代码3:
结果:

哈哈,结果很显然,在list中的实例依然是book这个实例本身,并没有新建一个,那么,list中所保存的不过是book的地址。为什么呢?下面,就要了解下java的内存存储机制啦。
下面转载内容从理论上描述的堆内存和栈内存的关系。
一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配
堆内存用于存放由new创建的对象和数组
数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。
Java中堆内存和栈内存详解
http://www.cnblogs.com/whgw/archive/2011/09/29/2194997.html
内容表述相对抽象,码友们可以边看文章边对照本文实验进行理解。
在本文的实验中,显然,变量 book 是 栈内存中 对存放在堆内存中Book对象的引用。而list所添加的是book这个变量,而非对象。真正的改变发生在堆内存中的Book中,因而产生了本实验中的效果。
最后,内心依然有一个疑问:在代码1中,我是将变量名book放在循环体外部,在循环体内部创建对象,那么 这种方式和 在循环体内部创建实体 Book book= new Book(); 在内存回收上有什么区别么? 是即时性不同还是 基本没有什么不同呢?
0 0