局部内部类就是声明在一个块(通常是方法)中的类。举例如下:
package innerclass; public class Outer1 { private String outerClassName = "Outer1"; public void printLocalClass(final boolean isPrintOuterClassName) { // 与常规内部类不同,局部内部类不能用public或者private修饰 class LocalClass implements Runnable { private String localClassName = "LocalClass"; @Override public void run() { // TODO Auto-generated method stub while (true) { try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } /** * 内部类可以访问外部类域和局部变量, 局部变量必须是final类型的 */ if (isPrintOuterClassName) { System.out.println(outerClassName + " " + localClassName); } else { System.out.println(localClassName); } } } } LocalClass localClass = new LocalClass(); Thread thread = new Thread(localClass); thread.start(); } }
public class TestOuter1 { public static void main(String[] args) { // TODO Auto-generated method stub Outer1 outer = new Outer1(); boolean isPrintName = true; } }
Outer1 LocalClass
Outer1 LocalClass
......
在局部内部类中访问外部类私有域的方法和常规内部类一致,这里需要解释的是局部类是如何访问局部变量的?
分析上面的printLocalClass()方法,方法执行完
thread.start();
语句就已经结束了,也就是说,isPrintOuterClassName这个变量在方法介绍后就不存在了,但是内部类的run方法中依然在使用这个变量?这是如何做到的呢?我们可以猜想,可能是在局部类中存储了isPrintOuterClassName变量的副本。事实也是如此,我们通过命令javap -private Outer1$1LocalClass来反编译Outer1$1LocalClass类文件,得到如下结果:
Compiled from "Outer1.java" class innerclass.Outer1$1LocalClass implements java.lang.Runnable { private java.lang.String localClassName; final innerclass.Outer1 this$0; private final boolean val$isPrintOuterClassName; innerclass.Outer1$1LocalClass(innerclass.Outer1, boolean); public void run(); }
前面还提到,局部内部类中只能引用final类型的局部变量,这是为了使局部变量和在局部内部类中的副本一致。