无法分配最终的局部变量,因为它是在封闭类型中定义的

sma*_*use 16 java final inner-classes

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());
Run Code Online (Sandbox Code Playgroud)

如果我写上面的代码Eclipse告诉我这个:

不能在不同方法中定义的内部类中引用非最终变量vote

但如果我在int vote之前添加final,它会给我这个错误:

无法分配最终的局部变量投票,因为它是在封闭类型中定义的

那么,如何解决?

Mar*_*nik 28

好吧,标准技巧是使用长度为1的int数组.使var final并写入var[0].确保不创建数据竞争非常重要.以您的代码为例:

final int[] vote = {0};

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

由于所有这些都将在EDT上发生,包括回调调用,你应该是安全的.您还应该考虑使用匿名类:

ratingS.addChangeListener(new ChangeListener() {
  public void stateChanged(ChangeEvent e) { vote[0] = ratingS.getValue(); }
});
Run Code Online (Sandbox Code Playgroud)

  • 我认为你应该*总是理解为什么某些东西起作用.在这种情况下,您只能从本地类中引用"final"变量,但是您无法更改它们.但是,无论指向数组的变量是否为final,您都可以*更改数组的内容. (5认同)

Pet*_*ler 5

移动voteSliderMoved:

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();
Run Code Online (Sandbox Code Playgroud)

编辑

或者,将模型类传递给更改侦听器

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
}
Run Code Online (Sandbox Code Playgroud)

Person 用法如下:

 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();
Run Code Online (Sandbox Code Playgroud)