2016-04-18 10 views
2

In meiner Java-Anwendung gibt es ein Verfahren ist, und es hat den folgenden Code:Lokale Java-Variable, auf die von der inneren Klasse aus zugegriffen wird; muss endgültig erklärt werden, warum es in NetBeans funktioniert?

JButton Button = new JButton(Content); 
Button.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent evt) { 
     doSomething(Button.getText()); 
    } 
}); 

Es kompiliert und arbeitet von NetBeans Fein 8.1, aber heute, wenn ich das Projekt von der Kommandozeile zu kompilieren versucht, es gab mir der folgende Fehler:

local variable Button is accessed from within inner class; needs to be declared final

Meine Frage ist: warum der gleiche Code entspricht und arbeitet von NetBeans 8.1 in Ordnung, aber in der Befehlszeile nicht kompilieren?

Meine Befehlszeilen Java-Version ist: 1.8.0_77

Und meine NetBeans Java-Version ist: 1.8.0_65

Das sollte keine Rolle spielen, also warum nicht NetBeans es nicht für einen Fehler entdeckt?

Edit: Woo, große Überraschung für mich, ich habe gerade einen Scheck auf javac:

C: \ Benutzer \ USER> java -version java version "1.8.0_77"

C: \ Benutzer \ USER> javac -Ausführung javac 1.7.0_40

Warten Sie eine Minute, ich bin 100% große Zeit verwirrt, zuerst habe ich nie wusste, dass es ein „javac -Ausführung“ Befehl ist, dachte ich, „java -verison“ werde mir sowohl java und javac sagen, und ich nehme an, sie sind die gleichen, zweitens, als ich Java installiert habe, dachte ich, das Installationsprogramm wird es automatisch aktualisieren, und javac ist Teil von Java, also sollte es intern konsistent sein, aber es ist definitiv NICHT, also wie kann meine Java-Version anders sein als meine Javac-Version? Mit anderen Worten, wie kann ich darauf vertrauen, dass Oracle mein Java und Javaac zur gleichen Zeit installiert, wenn es die Aufgabe nicht erfüllt, bedeutet das, dass ich jedes Mal, wenn ich Java aktualisiere, irgendwie meinen Javaac von Hand installieren muss? Das habe ich noch nie gemacht, also warum und wie konnte das passieren?

+1

Was ist die Zielplattform für Ihr Netbeans-Projekt? Bist du sicher, dass du den 'javac' verwendest, von dem du denkst, dass du ihn benutzt? Befehlszeilenpfade können Sie manchmal überraschen.Ihr Code sieht definitiv so aus, als müsste er für Java 8 kompilieren. – biziclop

+1

Ist Ihre Befehlszeile eine frühere Version von Java, vor 1.8? – rgettman

+1

Es sollte kompilieren, überprüfen Sie Ihre 'Javac' Version auf der Kommandozeile. – 11thdimension

Antwort

3

Vor Java 8 müssen alle lokalen Variablen, auf die in einer inneren Klasse zugegriffen werden muss, als final deklariert werden. Dies liegt an einem Implementierungsdetail - lokale Variablen werden als versteckte Instanzvariablen der inneren Klasse implementiert. Wenn die Variable geändert werden könnte, wäre die Kopie in der inneren Klasse falsch.

In Java 8 wurde diese Anforderung auf "final" oder "effectively final" (scrollen Sie etwa 2/3 des Weges) gelockert.

However, starting in Java SE 8, a local class can access local variables and parameters of the enclosing block that are final or effectively final. A variable or parameter whose value is never changed after it is initialized is effectively final.

Die Variablen nicht explizit final sein deklariert werden muss, es muss nur effektiv endgültig sein - nicht explizit final, nur nicht geändert.

Sie ändern nicht Button, so ist es effektiv endgültig und es kompiliert unter Java 8. Java 7 benötigt jedoch noch explizit final deklariert werden, so dass es einen Compilerfehler gibt.

Korrigieren Sie Ihren Pfad, sodass javac Ihre Java 8-Installation ist. Es ist möglich, dass Sie eine JRE (keine ausführbare Datei "javac") haben, die Java 8 ist, aber eine Installation von JDK 1.7 (Java 7), die Ihre Versionsausgabe erklären könnte. In diesem Fall müssten Sie das Java 8 JDK (1.8) herunterladen und installieren.