Warum wird eine lokale Variable in Java nicht als "effektiv final" betrachtet, obwohl sie danach nicht verändert wird?

7

In einer Methode habe ich das:

%Vor%

Ich verstehe nicht, warum es einen Kompilierungsfehler erzeugt. Der Fehler besagt, dass x nicht endgültig oder effektiv final ist und daher nicht vom Lambda-Body aus aufgerufen werden kann. Es gibt keine Änderung an x nach dem Aufruf doLater , daher wird der Wert von x bereits bestimmt, wenn doLater aufgerufen wird.

Ich vermute, dass die Antwort auf diese Frage ist, weil x nicht qualifiziert ist, eine effektiv endgültige Variable zu nennen. Ich möchte jedoch wissen, was der Grund ist.

Kann der Compiler nicht nur eine temporäre finale Variable erzeugen, die den Code effektiv wie folgt macht:

%Vor%

und alles funktioniert immer noch?

    
yuku 23.02.2016, 08:47
quelle

3 Antworten

15

Effektiv final bedeutet, dass es final hätte sein können, d. h. es ändert sich nie. Es bedeutet, dass die Variable effektiv ein final 1 sein könnte.

Das Problem ist, dass es nicht das letzte Mal, wenn Sie es geändert haben, verfolgt, sondern Sie es jemals geändert haben. Ändern Sie Ihre if -Anweisung in

%Vor%

oder

%Vor%     
Peter Lawrey 23.02.2016, 08:51
quelle
4

Ihre x Variable wäre effektiv gewesen, wenn sie einmal initialisiert und unter keinen Umständen wieder geändert wurde. Wenn du nur hättest:

%Vor%

dann hätte es kompiliert.

Wenn Sie jedoch Bedingungen hinzufügen, die möglicherweise ändern, ändert sich der Wert der Variablen

%Vor%

bewirkt, dass die Variable nicht effektiv final ist und somit der Kompilierfehler steigt.

Da dieser Zeiger Ansatz, den Sie implementiert haben, nicht funktionieren würde, könnten Sie außerdem Ihren Code ein wenig in eine einfache if-else-Anweisung umwandeln:

%Vor%

und loswerden von x .

    
Konstantin Yovkov 23.02.2016 08:51
quelle
2

Kurze Version, eine Variable ist effektiv final , wenn sie genau einmal zugewiesen ist, egal, welcher Codepfad ausgeführt wird.

Lange Version unter Angabe der Java-Sprachspezifikation 4.12. 4. letzte Variablen (Hervorhebung von mir):

  

Bestimmte Variablen, die nicht als final deklariert sind, werden stattdessen als effektiv final betrachtet:

     
  • Eine lokale Variable, deren Deklarator einen Initialisierer hat ( §14.4.2 ) ist effektiv endgültig , wenn alle folgenden Bedingungen zutreffen:      
    • Es ist nicht final deklariert.
    •   
    • Es tritt nie als linke Seite in einem Zuweisungsausdruck auf ( §15.26 ). (Beachten Sie, dass der lokale Variablendeklarator, der den Initialisierer enthält, nicht ein Zuweisungsausdruck ist.)
    •   
    • Es tritt niemals als Operand eines Präfix- oder Postfix-Inkrement- oder Dekrementoperators auf ( §15.14 , §15.15 ).
    •   
  •   

Jetzt können Sie es effektiv endgültig machen, indem Sie den Initialisierer entfernen, weil es fortfährt:

  
  • Eine lokale Variable, deren Deklarator keinen Initialisierer hat ist effektiv endgültig , wenn alle der folgenden Bedingungen erfüllt sind:      
    • Es ist nicht final deklariert.
    •   
    • Wenn es in einem Zuweisungsausdruck als linke Seite auftritt, ist es definitiv nicht zugewiesen und vor der Zuweisung nicht definitiv zugewiesen. das heißt, es ist definitiv nicht zugewiesen und nicht eindeutig nach der rechten Seite des Zuweisungsausdrucks zugewiesen ( §16 (eindeutige Zuordnung) ).
    •   
    • Es tritt niemals als Operand eines Präfix- oder Postfix-Inkrement- oder Dekrementoperators auf.
    •   
  •   
    
Andreas 23.02.2016 08:59
quelle

Tags und Links