2015-12-07 2 views
3

В школьном тесте я использовал не конечные переменные внутри внутреннего класса анонимного. На компьютере и на моем личном компьютере (с использованием x86 jre1.8.0_45) он работает.Java - Использование не конечных переменных в анонимном внутреннем классе?

Однако на учителях Eclipse для ноутбуков отображаются ошибки (переменные должны использовать final). Он использует версию jre1.8.0.x (не знаю точной версии).

Любые идеи, почему он работает на моем компьютере, а не на его компьютере?

В этом коде примера не конечный объект JLabel используется внутри функции actionPerformed в ActionListener:

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JLabel; 

public class Main { 
    public Main(String[] args) { 
     JLabel jLabel = new JLabel(); 
     JButton button = new JButton(); 
     button.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent arg0) { 
       jLabel.setText("xyz"); 

      } 
     }); 
    } 
} 
+2

Звучит странно, должна быть полевая переменная или объявлена ​​окончательной, насколько я могу судить – cYrixmorten

+0

Является ли это предупреждением или ошибкой? –

+2

Возможный дубликат [Java остановил ошибку при неконфигурированных переменных во внутренних классах (java 8)] (http://stackoverflow.com/questions/28408109/java-stopped-erroring-on-non-final-variables-in- inner-classes-java-8) – azurefrog

ответ

6

Новые версии Java более терпимы в этом относятся: они требуют только, что они должны быть «эффективно окончательным ».

В конце разница не слишком большая - вы можете использовать только переменные, которые вы МОЖЕТте пометить final; вы не можете изменять их.

Если вы находитесь в этом месте, вы также можете сделать их «действительно» final, и он работает везде.

Кстати, на 1,8 с новым синтаксисом лямбда вы можете написать более элегантно

button.addActionListener((ActionEvent arg0) -> jLabel.setText("xyz")); 
+0

. Более конкретно «эффективно финальный» был введен с Java 1.8 ... В предыдущих версиях он должен быть ** объявлен ** окончательным. – Codebender

+0

@Codebender Я так и думал, но OP, похоже, наблюдает это «старое» поведение и в версиях 1.8, если он не ошибается ... – glglgl

+0

«Новый» относительно. 7 и старше являются EoPU, устаревшими и больше не должны использоваться. –

0

Вы можете определить Слушатель не как анонимный класс, а как частный внутренний класс для того, чтобы избежать этой проблемы:

public class Main { 

    public Main(String[] args) { 

     JLabel jLabel = new JLabel(); 
     JButton button = new JButton(); 
     button.addActionListener(new MyActionListener(jLabel)); 
    } 

    private class MyActionListener implements ActionListener { 

     private JLabel jLabel; 
     MyActionListener(JLabel jLabel) { 
      this.jLabel = jLabel; 
     } 

     @Override 
     public void actionPerformed(ActionEvent arg0) { 
      jLabel.setText("xyz");    
     } 

    } 
} 

Таким образом, вы можете просто передать ярлык (и кнопку, если вам нужно) конструктору слушателя и сможете без проблем использовать его.

Смежные вопросы