2012-01-05 50 views
5

为什么SWING总是强迫我将某些特定对象标记为最终?由于这有时会使事情变得有点困难,有没有办法避免这种情况?Swing和最终修饰符

(不完全例),其中它迫使我的IExchangeSource变量标记为最终的:

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(); 
+3

你能举个例子吗?你是否正在讨论在匿名内部类中使用周围方法的变量?因为Swing本身没有什么能够强制你使变量成为'final'。 – Jesper 2012-01-05 15:36:15

+2

我敢打赌,你正在使用匿名内部类。 – 2012-01-05 15:37:04

回答

18

这有什么做摇摆,什么都没有。你应该显示你的代码有一个这样的例子,但可能你正在使用一个内部类,可能是一个匿名内部类,如果你使用这些,并尝试使用内部类的变量,其他块如构造函数),那么你需要使这些变量最终确定或者将它们提升到类字段。这又是一个要求,而不是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); 
     } 
    }); 
} 

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

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

  • 促进变量类字段,给它的范围。
  • 让匿名内部类调用外部类的方法。但是,这个变量仍然需要具有类范围。

编辑2 安东尼Accioly张贴解答了莫大的联系,但后来不知什么原因删掉了他的答案。我想在此发布他的链接,但很想看到他重新打开他的答案。

Cannot refer to a non-final variable inside an inner class defined in a different method

+0

感谢您的答案,是的,我正在使用内部类(请参阅示例)。对不起,最初没有添加示例。 – Cemre 2012-01-05 15:45:02

+0

@Cemre:请参阅编辑解决方案 – 2012-01-05 15:48:38

+0

@Cemre,对于没有发布示例,您有什么意思表示抱歉?您过去曾被问及在您的问题上发布SSCCE。每个问题都应包含SSCCE。 – camickr 2012-01-05 15:51:17