我作为公司半路出家的java程序员,对于java内存一无所知,在做到一些开发时,还竟然犯了一些低级错误,但是我不以为耻,反以为荣,我不喜欢究其原因,喜欢随便给个理由说服自己,下次不再犯同样的错误就行。
接下来我来说说我的低级错误:
@Test
public void test() {
TestPO testPO=new TestPO();
List<TestPO> longList=new LinkedList<TestPO>();
for(int i=0;i<5;i++) {
testPO.setMyLong(i);
longList.add(testPO);
}
for(TestPO t1:longList) {
System.out.println(t1.getMyLong());
}
}
我们用junit测试下,我当然认为输出的结果是0、1、2、3、4
可是实际上是:
呵呵,这是怎么回事?感觉没问题啊。为毛都是4?
那我的推测是for循环中,最后一次setMyLong(i)把之前已经add到list中的TestPO下的属性全部影响了。
于是我继续猜测内存中其实是怎样的一个过程,于是我画了个图,大概如下:
我在for循环中add了5次,可是指向的名称是同一个testPO,所以引用的既然是同一个,那么当我每次改变testPO中的属性时,那么longList中的对象也就同时被改变了。
所以,基于以上推测,如果想要输出0~4,那么就是每次需要5个不同的testPO对象。
所以代码我们这么改:
@Test
public void test() {
// TestPO testPO=new TestPO();不要放在for循环外
List<TestPO> longList=new LinkedList<TestPO>();
for(int i=0;i<5;i++) {
TestPO testPO=new TestPO();//放在for循环里
testPO.setMyLong(i);
longList.add(testPO);
}
for(TestPO t1:longList) {
System.out.println(t1.getMyLong());
}
}
这样我们循环下的结果:
达到我们的效果了。那么证明推测是大致正确的,对于内存中的样子应该是这样了。
每个list中都是独立的对象存在这样就不会影响之前的属性值了,当然我的测试代码比较简单,其实实际开发中只要用匿名对象就行了。
然后我就愉快出去玩耍了,其他的原因和原理也管不了这么多了,当然如有高手明白,还不吝赐教。