众所周知,想要在匿名内部类中用匿名内部类外部的变量需要定义成final,为什么呢?
private static ThreadFactory build(ThreadFactoryBuilder builder) {
final String nameFormat = builder.nameFormat;
final Boolean daemon = builder.daemon;
final Integer priority = builder.priority;
final UncaughtExceptionHandler uncaughtExceptionHandler =
builder.uncaughtExceptionHandler;
final ThreadFactory backingThreadFactory =
(builder.backingThreadFactory != null)
? builder.backingThreadFactory
: Executors.defaultThreadFactory();
final AtomicLong count = (nameFormat != null) ? new AtomicLong(0) : null;
return new ThreadFactory() {
@Override public Thread newThread(Runnable runnable) {
Thread thread = backingThreadFactory.newThread(runnable);
if (nameFormat != null) {
thread.setName(String.format(nameFormat, count.getAndIncrement()));
}
if (daemon != null) {
thread.setDaemon(daemon);
}
if (priority != null) {
thread.setPriority(priority);
}
if (uncaughtExceptionHandler != null) {
thread.setUncaughtExceptionHandler(uncaughtExceptionHandler);
}
return thread;
}
};
}
以上代码中的count本应在build方法执行完后会清理掉,该引用存在于栈内部中,方法结束,变量出栈,该引用指向的对象被gc。
但由于这个count定义成了final,这个时候局部内部类对象中包含有要访问的final型局部变量的一个拷贝,成为它的数据成员。虽然在build方法结束后,这个方法里的count引用出栈,但在由于在匿名内部类中有一份count引用的copy,所以count对象还有引用指向,不会被回收。相当于延长了局部变量count对象的生命周期。