Local variable needs to be declared final

2019-02-24 07:42发布

I'm receiving the error "local variable box is accessed from within inner class; needs to be declared final". That seems alright, but I don't really think it's the best solution, so I was hoping maybe someone else can help me out. Here is my code:

public void showPublisherBox(JComboBox box) {
    if (publisherBox == null) {
        publisherBox = new AddPublisherForm();
        publisherBox.setLocationRelativeTo(this);
    }
    publisherBox.addWindowListener(new WindowAdapter()
    {
    public void windowClosing(WindowEvent we)
    {
        this.populatePublishers(box);
    }

        private void populatePublishers(JComboBox box){
            box.setModel(db.getPublishers());
        }
    });
    publisherBox.setVisible(true);
}

Publisher form is just a new JFrame that opens up and takes in some information, and when it's closed I want the JComboBox to be repopulated via setting the model from my db.getPublishers() method.

So is there a better way to do what I'm doing here, or am I going to have to declare something as final?

Thanks

5条回答
虎瘦雄心在
2楼-- · 2019-02-24 08:26

Since you're not modifying box in the outer code, using final is exactly the correct way to solve this problem. It's a promise to yourself (and to the compiler) that the value of box won't change in the enclosing scope. The compiler will tell you if you break that promise.

There is no compile time or runtime cost to using final.

查看更多
Root(大扎)
3楼-- · 2019-02-24 08:30

You should type "Final" every single time you declare a variable--I have no idea why Java didn't make final the default and require a "Variable" keyword or something instead. I'm just saying most variables should be final unless proven otherwise.

That said, you can always make a full class instead of an anonymous inner class and pass the variable into the constructor--that would be the "Correct" way to do it. Anonymous inner classes are a bad habit anyway--they discourage code reuse (The inner class cannot be reused as a listener in another place, whereas if it were a full class it would be easily reused--I've used this technique when refactoring to eliminate huge piles of redundant code.

查看更多
手持菜刀,她持情操
4楼-- · 2019-02-24 08:33

Local variables used by local classes must be declared as final. In this case, the variable is a method parameter, which you don't assign to anyway, so I see no reason why not to declare it as final.

Needless to say, this declaration has no effect on the caller of the method whatsoever. It only states that the local copy of the reference is not modified by the body of the method.

查看更多
Lonely孤独者°
5楼-- · 2019-02-24 08:35

Nope. In this case, declare as final. The reference doesn't change anyway.

查看更多
Bombasti
6楼-- · 2019-02-24 08:37

When an anonymous inner class (such as your WindowAdapter) refers to variables in enclosing scopes (like 'box'), Java requires that they be declared final.

One way to avoid having to declare box as final would be to make your WindowAdapter a named class, that accepts the box as a constructor parameter:

public void showPublisherBox(JComboBox box) {
    if (publisherBox == null) {
        publisherBox = new AddPublisherForm();
        publisherBox.setLocationRelativeTo(this);
    }

    publisherBox.addWindowListener(new MyWindowClosingHandler(box, db));
    publisherBox.setVisible(true);
}

// ...

class MyWindowClosingHandler extends WindowAdapter {
    private JComboBox box;

    MyWindowClosingHandler(JComboBox box, DB db) {
        this.box = box;
        this.db = db;
    }

    public void windowClosing(WindowEvent we) {
        populatePublishers();
    }

    private void populatePublishers(){
        box.setModel(db.getPublishers());
    }
});

}

查看更多
登录 后发表回答