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;};
}
}
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;};
}
}
其实内部类本身就存在一些逻辑问题,例如内部类必须使用final参数才能传值,其实从实现的角度来看,这完全不用final都可以使用,但是java却规定需要final属性,这也因为一个逻辑问题,如果一个非final的值传入内部类,那么如果内部类改变了这个值,那么外部类的值是否需要改变,就变成一个逻辑难题,因此,设计者就干脆使用final类型,不允许修改。
这段详细描述,在java核心技术一书中有写到,大概是第五章。
这句话是关键,很多关于java的静态、非静态的用法规则都可以由这个理由推导出来
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修饰。