2012-03-31 10 views
1

ich diesen Code schrieb:Variable möglicherweise nicht haben benn für die endgültige Variable und anonyme Klasse initialisiert

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); 

Es ergibt dies:

Variable SchedulerHandle might not have benn initialized 

Was ist das Problem?
Wie kann ich es beheben?

+2

Ich sehe keine Variable namens 'ScheduledFuture' in Ihrem Code. (BTW, sollten Sie vermeiden, Variablen mit dem ersten Buchstaben als Kapital zu benennen, weil sie leicht mit Klassennamen verwechselt werden können.) –

+0

Mein Punkt ist, dass Sie uns wahrscheinlich nicht die tatsächliche Fehlermeldung zeigen ... –

+0

Entschuldigung. war ein Tippfehler. Ich habe die Frage bearbeitet. – RYN

Antwort

0

Da SchedulerHandle endgültig ist und Sie es nicht sofort definiert haben, warnt Ihr Compiler Sie, dass es in der run() -Methode möglicherweise nicht initialisiert wurde. einfach tun:

final ScheduledFuture SchedulerHandle = ExtractorTimer.scheduleWithFixedDelay (...

Update: Das war einfach falsch Mal sehen, Sie wollen alle 60 DB.buildConnection() aufrufen. Sekunden, bis True zurückgegeben wird Leider können Sie nicht auf SchedulerHandle verweisen, das von ScheduleWithFixedDelay() in dem Runnable zurückgegeben wird, mit dem Sie die Methode aufrufen, da das Runnable zuerst definiert werden muss - aber es nicht weiß, was SchedulerHandle ist t existiert an diesem Punkt

So ein alternativer Weg, um den Prozess der Aufhebung ist Ihr ScheduledExecutorService zu beenden, etwa so:

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); 

Aber beachten Sie, dass, wenn Sie dies tun, können Sie nicht ExtractorTimer Wiederverwendung und jede gegebene Aufgabe wird abgebrochen ! Future schedule() s wird ebenfalls nicht ausgeführt. Die einzige Möglichkeit, es wieder nutzbar zu machen, besteht darin, einen neuen ScheduledExecutorService zu erstellen - das ist der Nachteil dieses Ansatzes.

Wenn Sie mit ExtractorTimer nur für diese eine Aufgabe in Ordnung sind, sollte alles in Ordnung sein.

+0

tut dies keine Wirkung! und immer noch bekomme ich die Nachricht. – RYN

+0

Entschuldigung, ich habe es nicht zuerst überprüft, meine Antwort aktualisiert. – Anthales

+0

Als Alternative zum Herunterfahren des kompletten ThreadPools kann das 'Runnable' einfach eine' RuntimeException' auslösen. Das wird auch die Aufgabe stoppen. –

-2

Versuchen:

final ScheduledFuture<?> SchedulerHandle = null; 
+5

ROTFL. Das wird nicht wirklich helfen. –

+0

Probieren Sie es aus. Es löst das Problem in Netbeans Sieht für mich ziemlich logisch aus :-) – Hugues

+0

Haben Sie die kommende NPE in 'SchedulerHandle.cancel (false);'? Und auch die Zuordnung zu dieser endgültigen Variable? Wenn das in Netbeans wirklich funktioniert, werde ich diese IDE im nächsten Jahrzehnt nicht anfassen. –

1

Der Compiler ist richtig. Hier ist tatsächlich ein Problem.

Das Problem tritt aufgrund der Art auf, wie Java die Verwendung der SchedulerHandle-Variablen in der anonymen Runnable-Klasse behandelt. Wenn die Klasse Runnable instanziiert wird, wird ein synthetischer Konstruktorparameter verwendet, um den Wert SchedulerHandle an die anonyme Klasse zu übergeben. Dieser Wert wird in einem versteckten Attribut gespeichert, und das verwendet die run()-Methode ... nicht die Variable im Gültigkeitsbereich der Klasse.

Warum verursacht dies den Fehler?

Nun, der oben beschriebene Mechanismus bedeutet, dass SchedulerHandle initialisiert werden muss, bevor die Runnable Instanz erstellt wird. Aber in der Tat wird es später initialisiert, nachdem der scheduleWithFixedDelay Aufruf zurückgegeben wurde. Zu dem Zeitpunkt, zu dem der Wert der Variablen benötigt wird, wurde sie nicht initialisiert.

Verwandte Themen