Java中的内部类是在一个类内部定义的类。Java内部类大致可以分为四种类型:成员内部类、局部内部类、静态嵌套类和匿名内部类。
成员内部类
成员内部类指在一个类的内部定义另一个类,且成员内部类可以访问外部类的所有成员变量和方法(包括私有属性和方法)。成员内部类还可以拥有自己的成员变量和方法。下面是一个成员内部类的例子:
public class OuterClass {
private int outerNum = 1;
public void printInnerNum() {
InnerClass innerClass = new InnerClass();
innerClass.printNum(); // 可以直接调用InnerClass类的方法
}
public class InnerClass {
private int innerNum = 2;
public void printNum() {
System.out.println("innerNum: " + innerNum);
System.out.println("outerNum: " + outerNum);
}
}
}
局部内部类
局部内部类指在方法内部定义的类,在 Java8 后也允许在代码块中进行定义。局部内部类只能在定义它的方法 或代码块 中使用,由于作用域的限制其不能被其他方法使用。下面是一个局部内部类的例子:
public class OuterClass {
public void printNum() {
final int num = 10;
class InnerClass {
public void printMessage() {
System.out.println("The number is " + num);
}
}
InnerClass inner = new InnerClass();
inner.printMessage();
}
}
静态嵌套类
静态嵌套类指在一个类内部定义的 static 类,这个类一般是为外部类提供服务而存在。静态内部类不能直接访问其外部类的成员属性和方法,只能访问其静态成员变量、方法等静态资源。下面是一个静态嵌套内部类的例子:
public class OuterClass {
private static int outerNum = 1;
public static void printInnerNum() {
InnerClass innerClass = new InnerClass();
innerClass.printNum(); // 可以直接调用InnerClass类的方法
}
public static class InnerClass {
private static int innerNum = 2;
public void printNum() {
System.out.println("innerNum: " + innerNum);
System.out.println("outerNum: " + outerNum);
}
}
}
匿名内部类(JAVA8后可以用Lambda表达式简写)
匿名内部类是一种没有显式定义类名的内部类,在创建对象时定义并实现它(通常是通过覆盖已有的方法)。匿名内部类主要用于当对象只需使用一次时可以简化编程过程,同时也方便不需要专门定义类。下面是一个匿名内部类的例子:
public class OuterClass {
public void printMessage() {
Thread thread = new Thread(new Runnable() {
public void run() {
System.out.println("Hello world from a thread!");
}
});
thread.start();
}
}
这四种内部类的区别为:
- 成员内部类可以访问外部类的所有成员方法和属性,而局部内部类和匿名内部类只能访问方法中的 final 局部变量。
- 静态嵌套类是静态的,不依赖于外部类,它是作为其 outer class 的一个静态成员而存在的。而其他三种内部类都依赖于外部类被创建出来之后才能被创建。
实际应用:
成员内部类经常用于封装外部类的信息,在程序的各个部分都可以使用;而局部内部类和匿名内部类往往用于定义一次性的或者只有一个动作的、面向对象的代码块;而静态内部类则通常用于同时需要访问多个静态成员或构造函数的情况下,在整个项目中只有唯一一个实例等任务。