1。防止继承
2。
class Egg {
  protected class Yolk {
    public Yolk() {
      System.out.println("Egg.Yolk()");
    }
  }
  private Yolk y;
  public Egg() {
    System.out.println("New Egg()");
    y = new Yolk();
  }
}public class BigEgg extends Egg {
  public class Yolk {
    public Yolk() {
      System.out.println("BigEgg.Yolk()");
      private Yolk yy;
   ***public BigEgg() {
      System.out.println("New BigEgg()");
      yy = new Yolk();
   }    
  }
  public static void main(String[] args) {
    new BigEgg();
  }

***public BigEgg()还算是BigEgg的构造函数吗?它已经在Yolk类里了。所以会出现那个错误

解决方案 »

  1.   

    不好意思,第二个问题是我太粗心了。谢谢 flash007() 指出。但问题一, flash007() 兄还是没有说明白,final修饰符当然是为了防止继承,问题就是为什么要防止继承呀,请各位解释一下!
      

  2.   

    这条规则的翻译有问题,我想该是《java变成死相》的翻译出了问题
    如果一个匿名内部类出现在一个方法的内部,那么它如果它要访问这个方法的参数或者方法中定义的变量,则这些参数和变量必须被修饰为final
      

  3.   

    final是防止被其他类继承.看类的需要,如果觉的自类的功能已经很强大了那么当然就希望继续对它进行扩展重写
      

  4.   

    To cbu(阿牛) 兄:
    昨天第一个问题回答的不好(错误),今天看了一下书,特地补充一下,不足之处,请指正。
    匿名内部类使用在它外部定义的一个对象,并不是为了防止继承,而是由于匿名内部类没有构建器,它只能通过匿名内部类中对象的实例初始化进行构建。而对象的实例初始化应该是在编译期确定的,这样他们实例初始化的时候不能接收一个外部的在运行期才确定的数据,所以只能接收一个final类型的数据,因为final数据是一个编译期就确定下来的对象。
      

  5.   

    TO:flash007() 我觉得不是这个问题,你说的对匿名内部类的初始化只是方法之一,还可以通过初始化器(在内部类的定义域中被一对大括号封闭起来的部分)直接对各个字段进行初始化。另外,引用外部对象并不一定就是为了初始化这个内部类,比如引用外部对象的数据成员或方法。所以我觉得这应该不是必须得定义成FINAL的理由。还请大家继续~
      

  6.   

    To  cbu(阿牛): 我总算你弄明白了匿名内部类为什么只能用final.是变量的作用域的问题,因为匿名内部类是出现在一个方法的内部的,如果它要访问这个方法的参数或者方法中定义的变量,则这些参数和变量必须被修饰为final。因为虽然匿名内部类在方法的内部,但实际编译的时候,内部类编译成Outer.Inner,这说明内部类所处的位置和外部类中的方法处在同一个等级上,外部类中的方法中的变量或参数只是方法的局部变量,这些变量或参数的作用域只在这个方法内部有效。因为编译的时候内部类和方法在同一级别上,所以方法中的变量或参数只有为final,内部类才可以引用。你看看下面的例子:
    public class Outer{
      private int m = (int)(Math.random()*100);
      public static void main(String args[]){
        Outer that = new Outer();
        that.go((int)(Math.random()*100),(int)(Math.random()*100));
      }
      public void go(int x,final int y){
        int a = x+y;
        final int b = x-y;
        class Inner{
          public void method(){
            System.out.println("m is " + m);
    //        System.out.println("x is " + x);//非法
            System.out.println("y is " + y);
    //        System.out.println("a is " + a);//非法
            System.out.println("b is " + b);
          }
        }
        Inner that = new Inner();
        that.method();
      }
    }