这里要强调的是,局部变量同其所在语句块共存亡。语句块一般是由花括号括起来的(有时花括号可以省略,如:当if的语句块中只有一条语句时。一句虽然少,但我想应该也算一个语句块。)。当语句块执行完毕后,在该语句块中声明的变量会失效(典型而值得注意的例子是for循环语句:for(int i=0;i<5;i++){…},i在for语句执行好后,不能再用了;而在int i;for(i=0;i<5;i++){…}中,就没有问题)。
还要知道的是,对象不管在哪里生成,都不会立刻消失。这涉及到引用的概念,对对象的引用只是在变量里存了个地址,具体的对象数据不会同其引用共同存亡的。
所以,如果局部内部类生成的对象想访问其类所在的语句块中的局部变量,很肯能会出问题。索性Java设计者禁止了这种做法——编译不通过。
我在这里还注意到一个新的关于final的性质。前面学过用final修饰的成员变量,变成了常量。这里又提到了用final修饰的局部变量,也变成了常量。但是它不随其所在语句块的结束而失效。因此,局部内部类可以访问到它。
还有一种特殊的局部内部类,没有类名,叫做匿名内部类。我们知道,在创建对象时,必须知道所用类的名字。没有名字,到要用的时候怎么叫它来?当然叫不来了,但我们可以在它“出生”的时候就“抓住”它。也就是说,在定义匿名内部类的时候就创建其对象。还有,在定义这种类的时候需要“模板”(这样才能匹配)。“模板”可以是父类,也可以是接口。匿名内部类常用来实现图形界面中的事件相应。这里给个实例:
JButton btExit=new JButton(“exit”);
btExit.addActionListener(new ActionListener(){//ActionListener是JAVA API中已经定好的接口,并非类名。这是个匿名内部类(外部类已省略)。
public void actionPerformed(ActionEvent event){//接口中声明过的方法,这里实现了该方法。
System.exit(0);
}
});
匿名内部类因为是类,所以编译后独占一个.class文件。其命名方法与成员内部类一样,但由于内部类没有名称,就用序号来代替。