Java 内部类简介

120 阅读2分钟

这是我参与8月更文挑战的第25天,活动详情查看:8月更文挑战

Java 中,定义在另一个类或者方法中的类称作内部类。

内部类也称作嵌套类,包含内部类的类也被称作外部类(或者叫做宿主类)。可以定义多层次的内部类,此时把最外层的类成为顶层类(或者叫做顶级类)。

Java 内部类可以分为:

  • 成员内部类
    • 实例内部类(非静态内部类)
    • 静态内部类
  • 局部内部类
  • 匿名内部类

202108261421 Java 内部类的分类 00.png

JavaJDK 1.1 开始引入内部类,内部类主要有以下作用:

  • 内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类。假设需要创建 Cow 类,Cow 类需要组合一个 CowLeg 对象,CowLeg 类只有在 Cow 类里才有效,离开了 Cow 类之后没有任何意义。在这种情况下,就可把 CowLeg 定义成 Cow 的内部类,不允许其他类访问 CowLeg

  • 内部类成员可以直接访问外部类的私有数据,因为内部类被当成其外部类成员,同一个类的成员之间可以互相访问。但外部类不能访问内部类的实现细节,例如内部类的成员变量。

  • 匿名内部类适合用于创建那些仅需要一次使用的类。

  • 内部类需要定义在其他类或者方法中。

  • 内部类比外部类可以多使用三个修饰符:privateprotectedstatic。外部类不可以使用这三个修饰符。

  • 非静态内部类不能拥有静态成员,包括:

    • 静态成员变量
    • 静态方法
    • 静态初始化块
public class InnerNoStatic {
    private class InnerClass {
	    /*
		  下面都会引发编译错误:非静态内部类不能有静态声明
		*/
		static {
		    System.out.println("===");
		}
		private static int inProp;
		private static void test() {}
	}
}

非静态内部类里不可以有静态初始化块,但可以包含普通初始化块。非静态内部类普通初始化块的作用与外部类初始化块的作用完全相同。

内部类的特点如下:

  1. 内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的 .class 文件,但是前面冠以外部类的类名和 $ 符号。
  2. 内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否为 private 的。
  3. 内部类声明成静态的,就不能随便访问外部类的成员变量,仍然是只能访问外部类的静态成员变量。

参考资料

  • 疯狂 Java 讲义
  • cbiancheng.net