```java class Outer{ class Inner{ //内部类 } } ``` 上述定义的`Outer`是一个普通类,而`Inner`是一个Inner Class,它与普通类有个最大的不同,就是Inner Class的实例不能单独存在,必须依附于一个Outer Class的实例。 ```java public class Main{ public static void main(String[] args){ Outer outer = new Outer("hahaha"); Outer.Inter inner = outer.new Inner(); inner.hello(); } } class Outer{ private String name; Outer(String name){ this.name = name; } class Inner{ void hello(){ SYstem.out.println("Hello, "+Outer.this.name); } } } ``` 要实例化一个`Inner`,我们必须首先创建一个`Outer`的实例,然后,调用`Outer`实例的`new`来创建`Inner`实例。 # 匿名类 还有一种定义Inner Class的方法,它不需要在Outer Class中明确地定义这个Class,而是在方法内部,通过匿名类(Anonymous Class)来定义。 ```java public class Main{ public static void main(String[] args){ Outer outer = new Outer("hahaha"); outer.asyncHello(); } } class Outer{ private String name; Outer(String name){ this.name = name; } void asyncHello(){ Runnable r = new Runnable(){ @Override public void run(){ System.out.println("Hello, "+Outer.this.name); } }; new Thread(r).start(); } } ``` 观察`asyncHello()`方法,我们在方法内部实例化了一个`Runnable`。`Runnable`本身是接口,接口是不能实例化的,所以这里实际上是定义了一个实现了`Runnable`接口的匿名类,并且通过`new`实例化该匿名类,然后转型为`Runnable`。在定义匿名类的时候就必须实例化它,定义匿名类的写法如下 ```java Runnable r = new Runnable(){ //实现必要的抽象方法... } ``` 匿名类和Inner Class一样,可以访问Outer Class的`private`字段和方法。之所以我们要定义匿名类,是因为在这里我们通常不关心类名,比直接定义Inner Class可以少写很多代码。 观察Java编译器编译后的`.class`文件可以发现,`Outer`类被编译为`Outer.class`,而匿名类被编译为`Outer$1.class`。如果有多个匿名类,Java编译器会将每个匿名类依次命名为`Outer$1`、`Outer$2`、`Outer$3`。除了接口外,匿名类也完全可以继承自普通类。 # 静态内部类 最后一种内部类和Inner Class类似,但是使用`static`修饰,称为静态内部类(Static Nested Class)。 ```java public class Main{ public static void main(String[] args){ Outer.StaticNested sn = new Outer.StaticNested(); sn.hello(); } } class Outer{ private static String NAME = "OUTER"; private String name; Outer(String name){ this.name = name; } static class StaticNested{ void hello(){ System.out.println("Hello, "+Outer.NAME); } } } ``` 用`static`修饰的内部类和Inner Class有很大的不同,它不再依附于`Outer`的实例,而是一个完全独立的类,因此无法引用`Outer.this`,但它可以访问`Outer`的`private`静态字段和静态方法。如果把`StaticNested`移到`Outer`之外,就失去了访问`private`的权限。Static Nested Class是独立类,但拥有Outer Class的`private`访问权限。