Swing和final修饰符

Cem*_*mre 5 java swing

为什么SWING总是强迫我将某些特定物体标记为最终?因为这有时会使事情变得有点困难,有没有办法避免这种情况?

(INCOMPLETE EXAMPLE)它强制我将IExchangeSource变量标记为final:

public class MainFrame {

private final JTextArea textArea = new JTextArea();


public static void main(final IExchangeSource s) {
    EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {
            new MainFrame(s);
        }
    });
}
public MainFrame(final IExchangeSource s) {
    //build gui
    s.update();
Run Code Online (Sandbox Code Playgroud)

Hov*_*els 18

这有什么做摇摆,什么都没有.您应该显示具有此示例的代码,但可能您正在使用内部类,可能是匿名内部类,并且如果您使用这些并尝试在内部类中使用封闭方法本地的变量(或其他块,如构造函数),然后您需要使这些变量最终或将它们提升为类字段.同样,这是Java要求,而不是Swing要求.

一个Swing示例:

public MyConstructor() {
   final int localIntVar = 3;  // this must be final

   myJButton.addActionListener( new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
         // because you use the local variable inside of an anon inner class
         // not because this is a Swing application
         System.out.println("localIntVar is " + localIntVar);
      }
   });
}
Run Code Online (Sandbox Code Playgroud)

和一个非Swing示例:

public void myMethod() {
   final String foo = "Hello"; // again it must be final if used in 
                               // an anon inner class

   new Thread(new Runnable() {
      public void run() {
         for (int i = 0; i < 10; i++) {
            System.out.println(foo);
            try {
             Thread.sleep(1000);
            } catch (Exception e) {}

         }
      }
   }).start();
}
Run Code Online (Sandbox Code Playgroud)

有几种技巧可以避免这种情况:

  • 将变量提升为类字段,为其赋予类范围.
  • 让匿名内部类调用外部类的方法.但是,变量仍然需要具有类范围.

编辑2 安东尼Accioly发布了一个很棒的链接答案,但由于不明原因删除了他的答案.我想在这里发布他的链接,但很想看到他重新打开他的答案.

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

  • @Cemre:不客气.我不确定你为什么得到了低票.我们不是天生就知道Java,如果我们都因无知而被投票,那么我们都会有负面的声誉.向上投票支持反击者. (2认同)