Локальная переменная должна быть объявлена ​​окончательной - PullRequest
4 голосов
/ 01 мая 2011

Я получаю сообщение об ошибке «Доступ к локальной переменной осуществляется изнутри внутреннего класса; должен быть объявлен как финальный». Кажется, все в порядке, но я не думаю, что это лучшее решение, поэтому я надеялся, что, может быть, кто-то еще сможет мне помочь. Вот мой код:

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 - это просто новый JFrame, который открывается и получает некоторую информацию, и когда он будет закрыт, я хочу, чтобы JComboBox был повторно заполнен путем установки модели из моего метода db.getPublishers ().

Так есть ли лучший способ сделать то, что я делаю здесь, или мне придется объявить что-то как окончательное?

Спасибо

Ответы [ 5 ]

8 голосов
/ 01 мая 2011

Поскольку вы не изменяете box во внешнем коде, использование final - это как раз правильный способ решения этой проблемы.Это обещание для себя (и для компилятора), что значение box не будет меняться в пределах объема.Компилятор сообщит вам, если вы нарушите это обещание.

Нет времени компиляции или времени выполнения для использования final.

4 голосов
/ 01 мая 2011

Когда анонимный внутренний класс (например, WindowAdapter) ссылается на переменные во вложенных областях (например, 'box'), Java требует, чтобы они были объявлены final.

Один из способов избежатьобъявить box как final означало бы сделать ваш WindowAdapter именованным классом, который принимает box в качестве параметра конструктора:

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

}

1 голос
/ 01 мая 2011

Локальные переменные, используемые локальными классами, должны быть объявлены как final.В этом случае переменная является параметром метода, который вы в любом случае не назначаете, поэтому я не вижу причин, почему бы не объявить его как final

Излишне говорить, что это объявление никак не влияет на вызывающего метод.В нем только говорится, что локальная копия ссылки не изменяется в теле метода.

1 голос
/ 01 мая 2011

Неа.В этом случае объявить как окончательный.Ссылка все равно не меняется.

0 голосов
/ 02 мая 2011

Вы должны вводить «Final» каждый раз, когда объявляете переменную - я понятия не имею, почему Java не делает final значением по умолчанию и требует вместо него ключевое слово «Variable» или что-то в этом роде. Я просто говорю, что большинство переменных должны быть окончательными, если не доказано иное.

Тем не менее, вы всегда можете создать полный класс вместо анонимного внутреннего класса и передать переменную в конструктор - это был бы "правильный" способ сделать это. В любом случае анонимные внутренние классы являются вредной привычкой - они препятствуют повторному использованию кода (внутренний класс не может быть повторно использован в качестве слушателя в другом месте, тогда как если бы это был полный класс, его можно было бы легко повторно использовать - я использовал эту технику при рефакторинге устранить огромные кучи избыточного кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...