1.为什么java里,一个类的非static内部类不能有static变量或者方法??
public class Sc
{
class Vc
{
  static int i=0;  //error!
}
}
2.为什么匿名内部类在使用外部定义的对象时,编译器要求其参数引用是final的?
class sc
{
void f(int i)
{}
}class jh
{
sc func(int j)     //error 必须是final int j
{
return new sc(){private int k=j;};
}
}

解决方案 »

  1.   

    这是一个逻辑问题,static的东西,都是编译的时候就写进class文件中的,所以称为静态的,但是非静态的都是运行时才产生的东西,如果一个非静态的内部类中有一个静态的类,那么这样就出现逻辑冲突了,一个运行时产生的对象如何可能去产生一个编译时就产生的代码呢?
    其实内部类本身就存在一些逻辑问题,例如内部类必须使用final参数才能传值,其实从实现的角度来看,这完全不用final都可以使用,但是java却规定需要final属性,这也因为一个逻辑问题,如果一个非final的值传入内部类,那么如果内部类改变了这个值,那么外部类的值是否需要改变,就变成一个逻辑难题,因此,设计者就干脆使用final类型,不允许修改。
    这段详细描述,在java核心技术一书中有写到,大概是第五章。
      

  2.   

    对于第二个问题,java核心思想第六章上面的大概意思是,局部内部类只能访问局部的final变量,因为当一个函数结束时,局部 内部类还没有结束,还可能继续工作,而局部变量已经没有了,所以在一开始局部内部类就会保存一个局部变量的副本,这样子就不希望在修改保存后的值了,所以搞成了final的。
      

  3.   


    这句话是关键,很多关于java的静态、非静态的用法规则都可以由这个理由推导出来
      

  4.   

    可以有static的,可是要final的才可以~
      

  5.   

    对于普通局部变量而言,他的作用域就是停留在该方法内,当方法执行借宿,该局部变量也随之消失;但是内部类则可能产生隐式的“闭包(Closure)”,闭包将使局部变量脱离它所在的方法继续存在,例如:
    public class ClosureTest 
    {
    public static void main(String[] args)
    {
    //定义一个局部变量
    final String str = "Java";
    //在内部类里访问局部变量str
    new Thread(new Runnable()
    {
    public void run()
    {
    for (int i = 0; i < 100 ; i++ )
    {
    //此处将一直可以访问到str局部变量
    System.out.println(str + " " + i);
    //暂停0.1秒
    try
    {
    Thread.sleep(100);
    }
    catch (Exception ex)
    {
    ex.printStackTrace();
    }
    }
    }
    }).start();                        (1)
    //执行到此处,main方法结束
    }
    }
    正常情况下执行到(1)之后main方法的生命周期就结束了,那么str作用域也会结束,但只要新线程里的run方法没执行玩,匿名内部类的实例的生命周期就没有结束,将一直可以访问str局部变量的值。
        由于内部类可以扩大局部变量的作用域,如果再加上这个内部类的访问的局部变量没有使用final修饰,也就是可以随时改变,那将引起极大的混乱,因此,编译器要求所有被内部类访问的局部变量必须使用final修饰。