"=" 的先创建后引用

Java内存引用解析
自己在回答[url]http://www.iteye.com/problems/15359[/url]的问题得到了奖励,但是自己有时间也做了一下试验,但是结果发现自己的回答是错误的,起码是“ [color=red]elementData指向了新的内存块[/color]”这句话是错误的。当时以为“=”是先引用后创建的呢,自以为这样可以保证创建过程的安全性。但是我做了这样的例子:


public class TestRef
{
public Object 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 block
null
null
---------------------------------------
non static block
null
null
---------------------------------------
constructor
null
null
---------------------------------------
Persion@c17164
---------------------------------------
non static block
null
null
---------------------------------------
constructor
null
null
---------------------------------------
Persion@1fb8ee3


[color=red] 两次创建说明在new过程中 static block , block, 一直到 构造函数[/color],说明都没有引用而是构造函数结束后才引用。
为了证明是不是时间太短的原因,又做了一个例子:

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@61de33
TestRef@61de33
TestRef@61de33
TestRef@61de33
TestRef@61de33
TestRef@61de33
TestRef@61de33
TestRef@61de33
TestRef@61de33
TestRef@61de33
---------------------------------------
TestRef@8d5190

[color=red]这应该可以说明在新对象创建完成的时候,“=”才起作用把引用赋给对象[/color],这样就说明在arraylist源代码ensureCapacity方法中:

elementData = Arrays.copyOf(elementData, newCapacity);

在copyOf没有内部如果没有给[color=red]elementData[/color]赋新值的话,[color=red]elementData[/color]的引用一直还是老的引用,证明老的[color=red]elementData[/color]还算是安全的。如果说这样的话,源代码中
Object oldData[] = elementData
存在的意义起码我的有些说法就不成立了。
唉!本以为自己回答了一个很好的问题,但是今天却发现时错误的,有点伤心!不知道怎么能修正过来,觉得自己误人了。但是也有些疑惑,就是[color=red]如果“=”是先创建后引用的话,如果创建的时间比较长,如果在多线程的环境下,怎么保证自己的创建不被垃圾回收器回收呢?[/color]或许java有自己的保护机制吧。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值