final 与 匿名内部类

众所周知,想要在匿名内部类中用匿名内部类外部的变量需要定义成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对象的生命周期。

猜你喜欢

转载自lianglaiyang.iteye.com/blog/2257860