怎么写能不设成static呢
class TravelThread extends Thread
{
/////////////////////这个地方改成了非static
private final AtomicInteger ThreadCount = new AtomicInteger();
private String channel;
public TravelThread(String channel)
{
////////////////////////////这个地方要求我改成static
super("travel-file-thread-" + ThreadCount.incrementAndGet());
this.channel = channel;
}
public void run()
{
try
{
writeresult(channel);
}
catch (Throwable e)
{
onException(e, channel);
}
// System.out.println("threadover is .");
}
------解决思路----------------------
首先说明一下:
因为题主没有说明AtomicInteger 是来自哪一个包,所以我默认为是java.util.concurrent.atomic.AtomicInteger。
我们查看源代码发现
这是变量定义:
public class AtomicInteger extends Number implements java.io.Serializable {
private static final long serialVersionUID = 6214790243416807050L;
// setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
private volatile int value;
这是题主用到的初始化:
public AtomicInteger() {
}
这是题主用到的AtomicInteger 的 incrementAndGet() 方法:
public final int incrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}
我们发现incrementAndGet() 方法调用了unsafe,而unsafe 在这里是一个静态对象。
在Thinking In Java 一书中是这样描述的:
1.Java 尽力保证,所有变量在使用前都能得到恰当的初始化。所以 变量会在任何方法(包括构造器)被调用之前得到初始化【5.7.1】 在有静态对象的情况下是先静态对象,后非静态对象。(注:这是很好理解的,因为静态对象可以在类被实例化之前调用,所以优先初始化的等级一定高于非静态对象的)。
2.在类里定义一个对象引用时,如果不将其初始化,此引用就会获得一个特殊值 null。 【5.6】
所以在有继承时,变量的初始化情况是:
1 继承体系的所有静态成员初始化(先父类,后子类)
2 父类初始化完成(普通成员的初始化-->构造函数的调用)
3 子类初始化(普通成员-->构造函数)
为了便于理解:
将题主代码中所涉及到得带入图中,很容易能够得知为什么了。
------解决思路----------------------
当然不行,子类的实例化必须依赖于父类,而成员变量属于实例而不是类。所以调用super时就是初始化父类,而此时子类还未实例化,所以super()中不能调用任何子类自己的非静态成员变量。