доступ к переменной внутри внутреннего класса в java
Я пытаюсь создать массив JLabels, все они должны стать невидимыми при нажатии. Проблема возникает при попытке настроить прослушиватель мыши через внутренний класс, который нуждается в доступе к переменной итерации цикла, используемой для объявления меток. Код не требует пояснений:
for(int i=1; i<label.length; i++) {
label[i] = new JLabel("label " + i);
label[i].addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
label[i].setVisible(false); // compilation error here
}
});
cpane.add(label[i]);
}
Я думал, что смогу преодолеть это с помощью this
или, может быть,super
вместо вызова label[i]
внутри внутреннего метода, но я не был в состоянии понять это из.
ошибка компиляции: доступ к локальной переменной i осуществляется из внутреннего класса; необходимо объявить final'
Я уверен, что ответ должен быть чем-то действительно глупым, о чем я не думал, или, может быть, я делаю какую-то небольшую ошибку.
любая помощь будет оценили
5 ответов
локальная переменная должна быть final
для доступа из внутреннего (и анонимного) класса.
вы можете изменить свой код для чего-то вроде этого :
for (int i = 1; i < label.length; i++) {
final JLabel currentLabel =new JLabel("label " + i);
currentLabel.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
currentLabel.setVisible(false); // No more compilation error here
}
});
label[i] = currentLabel;
}
из JLS:
любая локальная переменная, формальный параметр или параметр исключения, используемые, но не объявленные во внутреннем классе должны быть объявлены
final
.любая локальная переменная, используемая, но не объявленная во внутреннем классе, должна быть определенно назначена (§16) перед телом внутреннего класса.
ресурсы :
Если у вас возникли проблемы с доступом i
, сделайте другую переменную вне области вашего внутреннего класса (например, до label[i].addMouseListener(...)
):
for(int i=1; i<label.length; i++) {
label[i] = new JLabel("label " + i);
final int localI = i;
label[i].addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
label[localI].setVisible(false);
}
});
cpane.add(label[i]);
}
вы также можете использовать getSource
в вашей программе. После этого вы можете получить доступ к своему компоненту с помощью typecasting
. это уменьшит дополнительные строки кода,
ваш код будет выглядеть следующим образом
for (int i = 1; i < label.length; i++) {
currentLabel.addMouseListener(new MouseAdapter(e) {
public void mouseClicked(MouseEvent me) {
JLabel label = (JLabel) me.getSource();
}
});
}
это происходит потому, что label
Не указан как final
.
объявите массив меток как:
final JLabel[] label;
вместо:
JLabel[] label;
код MouseAdapter
не является внутренним классом; это аноним класса. Анонимные классы могут ссылаться только на final
переменные включающего кода.
анонимные внутренние классы могут обращаться только к переменным метода enclosing, которые являются final
.