The final local variable cannot be assigned, since

2019-03-15 00:43发布

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

If i write the above code Eclipse tells me this:

Cannot refer to a non-final variable vote inside an inner class defined in a different method

But if i add final before int vote it gives me this error:

The final local variable vote cannot be assigned, since it is defined in an enclosing type

So, how to solve?

4条回答
我只想做你的唯一
2楼-- · 2019-03-15 00:51

Move vote to 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

Or alternatively, pass a model class to the change listener

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 is used as follows:

 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();
查看更多
等我变得足够好
3楼-- · 2019-03-15 00:53

I finally solved declaring vote as instance variable (private) in the main class.

查看更多
啃猪蹄的小仙女
4楼-- · 2019-03-15 01:03

Setting the Compiler compliance level to 1.8 worked for me to solve a similar problem. I don't understand the reason but you may try this.

How it works:

Right click on the project --> Properties --> Java Compiler. And in java compiler properties window, set the compiler compliance level to 1.8.

查看更多
▲ chillily
5楼-- · 2019-03-15 01:13

Well, the standard trick is to use an int array of length one. Make the var final and write to var[0]. It is very important to make sure you don't create a data race. Using your code as an example:

final int[] vote = {0};

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

Since all this will be happenenig on the EDT, including the callback invocation, you should be safe. You should also consider using the anonymous class:

ratingS.addChangeListener(new ChangeListener() {
  public void stateChanged(ChangeEvent e) { vote[0] = ratingS.getValue(); }
});
查看更多
登录 后发表回答