小弟菜鸟,请教大家个问题,如下:import java.awt.*;
import java.awt.event.*;
public class Test007 {
    private  Frame f = null;
    private  Button b = null;
    public Test007(Frame f,Button b)
    {
     this.f = f;
     this.b = b;
    }
    
    //问题:在init方法中,用匿名内部类实现事件监听器 ,编译执行正确
    void init()
    {
     f.add(b,"South"); //MARK:Use the anonymous inner class to register the event 
     b.addMouseListener(new MouseAdapter()
     {
     public void mouseReleased(MouseEvent e)
     {
     b.setLabel("u just release the mouse and the window will bu shutted down in 5 sec...");
     try
     {
     Thread.sleep(5000);
     }
     catch(Exception ex)
     {
     ex.printStackTrace();
     }
     f.dispose();
     System.exit(0);
     }
   });

     f.setVisible(true);
     b.setVisible(true);
    }
    
    public static void main(String[] args) {
     new Test007(new Frame("MarkWin"),new Button("exit")).init();
    }
}
但是,将init()方法中的实现代码,放在Test007类的构造函数中,编译出错:local variable f is accessed from within inner class; needs to be declared final
提示内部类只能访问外部类的final类型成员import java.awt.*;
import java.awt.event.*;
public class Test007 {
    private  Frame f = null;
    private  Button b = null;
    public Test007(Frame f,Button b)
    {
     this.f = f;
     this.b = b;
     f.add(b,"South");
     b.addMouseListener(new MouseAdapter()
     {
     public void mouseReleased(MouseEvent e)
     {
     b.setLabel("u just release the mouse");
     f.dispose();
     System.exit(0);
     }
   });
     f.setVisible(true);
     b.setVisible(true);
    }   
    public static void main(String[] args) {     new Test007(new Frame("MarkWin"),new Button("exit"));
    }
}

解决方案 »

  1.   


    private Frame fa = null;    private Button ba = null;    public Test(Frame f, Button b) {
            this.fa = f;
            this.ba = b;
            fa.add(b, "South");        // MARK:Use the anonymous inner class to register the event
            ba.addMouseListener(new MouseAdapter() {
                public void mouseReleased(MouseEvent e) {
                    ba
                            .setLabel("u just release the mouse and the window will bu shutted down in 5 sec...");
                    try {
                        Thread.sleep(5000);
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                    fa.dispose();
                    System.exit(0);
                }
            });        fa.setVisible(true);
            ba.setVisible(true);
        }由于你把这段代码移入到构造函数中,而构造函数的参数名与你的私有属性相同的变量名,所以编译出错
    将你的私有属性或参数名更改了~~
      

  2.   

    呵呵@LZ 在研究内部类的吧!你可能忘记一句话,内类要引用外部变量时,被引用的外部变量一定要被声明为“final”类型的,这是死规矩!core Java 中说的很详细,LZ愿意的话,可以参考一下!Local classes have another advantage over other inner classes. Not only can they access the fields of their outer classes, they can even access local variables! However, those local variables must be declared final. Here is a typical example. Let's move the interval and beep parameters from the TalkingClock constructor to the start method.public void start(int interval, final boolean beep)
    {
       class TimePrinter implements ActionListener
       {
          public void actionPerformed(ActionEvent event)
          {
              Date now = new Date();
              System.out.println("At the tone, the time is " + now);
              if (beep) Toolkit.getDefaultToolkit().beep();
          }
      }   ActionListener listener = new TimePrinter();
       Timer t = new Timer(1000, listener);
       t.start();
    }
      

  3.   

    3楼正解,如果将构造函数的参数改名,不和私有变量同名的话,编译正常。
    但是4楼的回答:However, those local variables must be declared final .
    我在此处没有将外部类的成员变量定义成Final, 在内部类也是可以正确引用到的啊。为了验证是否因为 构造函数的参数名与私有属性的变量同名而造成编译错误
    若将变量不设为private ,则编译应该没问题的。如下:
    import java.awt.*;
    import java.awt.event.*;
    public class Test007 {
          Frame fa = null;
          Button bo = null;

        public Test007(Frame fa,Button bo)
        {
         this.fa = fa;
         this.bo = bo;
         fa.add(bo,"South");
         bo.addMouseListener(new MouseAdapter()
         {
         public void mouseReleased(MouseEvent e)
         {
         bo.setLabel("u just release the mouse");
         fa.dispose();
         System.exit(0);
         }
       });
         fa.setVisible(true);
         bo.setVisible(true);
        }
    }但是编译还是出现local variable f is accessed from within inner class; needs to be declared final 这样的提示错误。
      

  4.   

    我来说几句吧  
    当内部类要用到外部类局部变量的时候  必须声明为final的
    为什么呢?想想局部变量吧  当方法返回的时候 局部变量就不存在了  那内部类怎么通过局部变量调用呢
    so你的例子中不用声明final是因为你用到的类的实例变量
    啊 你说为什么第二个不行  因为第二个的构造函数中用到了正式局部变量
    仔细看看就明白了 注意构造器参数的命名
      

  5.   

    However, those local variables must be declared final.这个英文的意思是“外部'局部变量'被内部类引用时,该局部变量必须被定义为final的”这个不是我说的(呵呵,我是菜鸟),这是core Java 卷一中的经典句子啊!也是广大Java人的认同的,呵呵!LZ我说的没有错的!呵呵! 局部变量和类变量要搞清楚啊!