内部类指的是在一个类的内部定义的类,Java 中存在四种内部类,分别是成员内部类、局部内部类、静态内部类和匿名内部类。
成员内部类
成员内部类在类文件中与成员变量和成员方法并列,作为类的成员存在。
成员内部类可以访问外部类的所有成员,成员内部类不可以定义静态成员。
java
public class Outer {
private String a = "a";
class Inner {
private String b = "b";
void hello() {
System.out.println(Outer.this.a + " " + b);
}
}
}
要实例化一个成员内部类,必须先实例化外部类,通过外部类实例实例化一个成员内部类。
java
public class Main {
public static void main(String[] args) {
Outer out = new Outer();
Outer.Inner inner = out.new Inner();
inner.hello();
}
}
局部内部类
局部内部类指定义在成员方法或者代码块中的类,对它的访问仅限于定义它的方法或代码块内。
局部内部类可以访问外部类所有成员,如果要访问局部变量,则变量必须被 final 修饰。局部内部类不能定义静态成员。
java
public class Outer {
private String a = "123";
public void hello() {
final String b = "b";
class PartInnerClass{
private String c = "c";
public void hello() {
System.out.println(a + b + c);
outerMethod();
}
}
PartInnerClass partInnerClass = new PartInnerClass();
partInnerClass.hello();
a = "aa";
}
private void outerMethod(){
System.out.println(a);
a = "aa";
}
}
静态内部类
静态内部类的定义和成员内部类类似,只是比成员内部类多了一个 static 修饰符。
静态内部类不可以访问外部类非静态成员。
java
public class Outer {
private String a = "a";
private static String staticA = "a";
private void outerMethod(){
a = "aa";
System.out.println(a);
}
static class staticInnerClass{
private String b = "b";
public void innerMethod(){
System.out.println(staticA + b);
}
}
}
静态内部类不再依附于外部类,这点和静态成员有点类似。
java
public class Main {
public static void main(String[] args) {
Outer.staticInnerClass inner = new Outer.staticInnerClass();
inner.innerMethod();
}
}
匿名内部类
匿名内部类在 Java 中用于实现接口和抽象类,它也可以继承普通类,但是很少使用。
匿名内部类可以访问外部类的所有成员。匿名内部类如果要访问局部变量,则该局部变量必须被 final 修饰。
匿名内部类不能定义静态成员。
java
public class Outer {
private String a = "a";
private void outerMethod(){
String c = "c";
Runnable r = new Runnable() {
private String b = "b";
@Override
public void run() {
System.out.println(a + b + c);
}
};
r.run();
}
}