繁体   English   中英

变量可能没有为最终变量和匿名类初始化benn

[英]Variable might not have benn initialized for final variable and anonymous class

我写了这段代码:

ScheduledExecutorService ExtractorTimer=Executors.newScheduledThreadPool(1);
final ScheduledFuture<?> SchedulerHandle;
SchedulerHandle =ExtractorTimer.scheduleWithFixedDelay(
    new Runnable() {
        public void run() {
            if(DB.buildConnection()){
                  SchedulerHandle.cancel(false);
            }
        }
     },0, 60,java.util.concurrent.TimeUnit.SECONDS);

它给出了:

Variable SchedulerHandle might not have benn initialized

问题是什么?
我该如何解决?

编译器是正确的。 实际上这里有一个问题。

出现问题是由于Java处理匿名Runnable类中SchedulerHandle变量的使用的方式。 实例化Runnable类时,将使用综合构造函数参数将SchedulerHandle的值传递给匿名类。 这个值存储在一个隐藏的属性中,这就是run()方法使用的...而不是包围该类的作用域中的变量。

那为什么会导致错误呢?

好了,我上面描述的机制意味着在创建Runnable实例之前需要初始化SchedulerHandle 但实际上,在scheduleWithFixedDelay调用返回之后,它会在以后初始化。 因此,在需要该变量的值时,尚未对其进行初始化。

因为SchedulerHandle是最终的,并且您没有立即定义它,所以编译器会警告您,它可能未在run()方法中初始化。 只需做:

最后的ScheduledFuture SchedulerHandle = ExtractorTimer.scheduleWithFixedDelay(...

更新:那是完全错误的。 让我们看看,您想每60秒调用一次DB.buildConnection(),直到它返回true。 不幸的是,您不能在调用该方法的Runnable中引用从scheduleWithFixedDelay()返回的SchedulerHandle,因为必须首先定义Runnable-但它不知道什么是SchedulerHandle,因为它当时不存在。

因此,取消该过程的另一种方法是终止ScheduledExecutorService,如下所示:

ScheduledExecutorService ExtractorTimer=Executors.newScheduledThreadPool(1);
final ScheduledFuture<?> SchedulerHandle;
SchedulerHandle =ExtractorTimer.scheduleWithFixedDelay(
    new Runnable() {
        public void run() {
            if(DB.buildConnection()){
                  ExtractorTimer.shutdown();
            }
        }
    },0, 60,java.util.concurrent.TimeUnit.SECONDS);

但是请注意,如果执行此操作,则无法重用ExtractorTimer, 任何给定的任务都将被取消! 将来的时间表也将不会执行。 使它再次可用的唯一方法是创建一个新的ScheduledExecutorService-这是此方法的缺点。

因此,如果您可以只将ExtractorTimer用于一项任务,那么一切都会很好。

尝试:

final ScheduledFuture<?> SchedulerHandle = null;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM