"=" 的先创建后引用
自己在回答http://www.iteye.com/problems/15359的问题得到了奖励,但是自己有时间也做了一下试验,但是结果发现自己的回答是错误的,起码是“ elementData指向了新的内存块”这句话是错误的。当时以为“=”是先引用后创建的呢,自以为这样可以保证创建过程的安全性。但是我做了这样的例子:public class TestRef{publicObject A;public static Object B;public static void main(String[] args){TestRef test = new TestRef();System.out.println("---------------------------------------");test.A = new Persion();System.out.println(test.A);System.out.println("---------------------------------------");test.B = new Persion();System.out.println(test.B);}class Persion{private static TestRef test = new TestRef();static {System.out.println("Static block");System.out.println(test.A);System.out.println(test.B);System.out.println("---------------------------------------");}{System.out.println("non static block");System.out.println(test.A);System.out.println(test.B);System.out.println("---------------------------------------");}Persion(){System.out.println("constructor");System.out.println(test.A);System.out.println(test.B);System.out.println("---------------------------------------");}}
得出的结果是这样的
Static blocknullnull---------------------------------------non static blocknullnull---------------------------------------constructornullnull---------------------------------------Persion@c17164---------------------------------------non static blocknullnull---------------------------------------constructornullnull---------------------------------------Persion@1fb8ee3
两次创建说明在new过程中 static block , block, 一直到 构造函数,说明都没有引用而是构造函数结束后才引用。
为了证明是不是时间太短的原因,又做了一个例子:
public class TestRef{public static Object C;public static void main(String[] args){ TestRef test = new TestRef();TestRef.C = new TestRef();System.out.println(test.C);TestRef.C = Persion.getRef();System.out.println(test.C);}}class Persion{private static TestRef test = new TestRef();public static TestRef getRef(){System.out.println("---------------------------------------");for(int i=0; i<10; i++){System.out.println(TestRef.C);for(int j=0; j<100000000; j++){new TestRef();}}System.out.println("---------------------------------------");return new TestRef();}}
这个例子的结果是:
TestRef@61de33---------------------------------------TestRef@61de33TestRef@61de33TestRef@61de33TestRef@61de33TestRef@61de33TestRef@61de33TestRef@61de33TestRef@61de33TestRef@61de33TestRef@61de33---------------------------------------TestRef@8d5190
这应该可以说明在新对象创建完成的时候,“=”才起作用把引用赋给对象,这样就说明在arraylist源代码ensureCapacity方法中:
elementData = Arrays.copyOf(elementData, newCapacity);
在copyOf没有内部如果没有给elementData赋新值的话,elementData的引用一直还是老的引用,证明老的elementData还算是安全的。如果说这样的话,源代码中
Object oldData[] = elementData存在的意义起码我的有些说法就不成立了。
唉!本以为自己回答了一个很好的问题,但是今天却发现时错误的,有点伤心!不知道怎么能修正过来,觉得自己误人了。但是也有些疑惑,就是如果“=”是先创建后引用的话,如果创建的时间比较长,如果在多线程的环境下,怎么保证自己的创建不被垃圾回收器回收呢?或许java有自己的保护机制吧。
页:
[1]