webentwicklung-frage-antwort-db.com.de

Die letzte lokale Variable kann nicht zugewiesen werden, da sie in einem einschließenden Typ definiert ist

ratingS = new JSlider(1, 5, 3); 
ratingS.setMajorTickSpacing(1);
ratingS.setPaintLabels(true);
int vote;

class SliderMoved implements ChangeListener {
    public void stateChanged(ChangeEvent e) {
        vote = ratingS.getValue();
    }
}

ratingS.addChangeListener(new SliderMoved());

Wenn ich den obigen Code schreibe, sagt mir Eclipse:

Kann sich nicht auf eine nicht endgültige variable Abstimmung innerhalb einer inneren Klasse beziehen in einer anderen Methode definiert

Wenn ich jedoch final vor int vote hinzufüge, wird mir dieser Fehler angezeigt:

Die letzte lokale Variable vote kann nicht zugewiesen werden, da sie in einem einschließenden Typ definiert ist

So wie zu lösen?

16
smartmouse

Nun, der Standard-Trick besteht darin, ein int-Array von Länge eins zu verwenden. Machen Sie das var final und schreiben Sie in var[0]. Es ist sehr wichtig sicherzustellen, dass Sie kein Datenrennen erstellen. Verwenden Sie Ihren Code als Beispiel:

final int[] vote = {0};

class SliderMoved implements ChangeListener {
  public void stateChanged(ChangeEvent e) {
    vote[0] = ratingS.getValue();
  }
}

Da dies alles auf dem EDT einschließlich des Rückrufaufrufs geschehen wird, sollten Sie sicher sein. Sie sollten auch die anonyme Klasse verwenden:

ratingS.addChangeListener(new ChangeListener() {
  public void stateChanged(ChangeEvent e) { vote[0] = ratingS.getValue(); }
});
27
Marko Topolnik

Verschiebe vote nach SliderMoved:

class SliderMoved implements ChangeListener {
    private int vote;
    public void stateChanged(ChangeEvent e) {
        this.vote = ratingS.getValue();
        // do something with the vote, you can even access
        // methods and fields of the outer class
    }
    public int getVote() {
        return this.vote;
    }
}

SliderMoved sm = new SliderMoved();
ratingS.addChangeListener(sm);

// if you need access to the actual rating...
int value = rattingS.getValue();

// ...or
int value2 = sm.getVote();

EDIT

Oder übergeben Sie alternativ eine Modellklasse an den Änderungslistener

public class Person {
    private String name;
    private int vote;
    public int getVote() {
        return this.vote;
    }
    public void setVote(int vote) {
        this.vote = vote;
    }
    // omitting other setter and getter
}

Person wird wie folgt verwendet:

 class SliderMoved implements ChangeListener {
    private Person person;
    public SliderMoved(Person person) {
        this.person = person;
    }
    public void stateChanged(ChangeEvent e) {
        this.person.setVote(ratingS.getValue());
    }
    public Person getPerson() {
        return this.person;
    }
}

Person person = new Person();

ratingS.addChangeListener(new SliderMoved(person));

// access the vote
int vote = person.getVote();
5
Peter Keller

Die Einstellung des Compiler-Übereinstimmungsgrads auf 1,8 funktionierte für mich, ein ähnliches Problem zu lösen. Ich verstehe den Grund nicht, aber Sie können es versuchen.

Wie es funktioniert:

Klicken Sie mit der rechten Maustaste auf das Projekt -> Eigenschaften -> Java Compiler. Legen Sie im Java-Compiler-Eigenschaftenfenster die Compiler-Compliance-Ebene auf 1,8 fest.

2
Nadeem

Ich habe es schließlich gelöst, die Abstimmung als Instanzvariable (privat) in der Hauptklasse zu erklären.

2
smartmouse