簡體   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