- Java中的内部类有四种:成员内部类、局部内部类、静态内部类和匿名内部类
概念
- 内部类:在Java中,程序是由类(class)构成的,在一个类的内部也可以声明类,把声明在另一个类内部的类叫做内部类
作用
- 实现了更好的封装,普通类(非内部类)的访问修饰符不能为private或protected,而内部类可以。当我们将内部类声明为private时,只有外部类可用于访问内部类,这样就很好的隐藏了内部类
- 内部类可以继承或实现其他的类或接口,而不受外部类的影响
- 内部类可以直接访问外部类的字段和方法,即使是用private修饰的,但外部类不能直接访问内部类的成员
- 注意:内部类是一个编译时的概念,编译后会生成两个独立的class文件
如:
- 注意:内部类是一个编译时的概念,编译后会生成两个独立的class文件
public class Outer{
private String outerName = "outer";
class Inner{
private String innerName = "inner";
}
}
编译后生成两个文件:Outer.class和Outer$Inner.class
分类
1. 成员内部类
- 即作为外部类的一个成员存在,与外部类的属性、方法并列。
- 成员内部类中不能声明静态成员(但static final的基本类型变量除外,因为在编译时就会被变成常量值),因为加载类时,会先初始化静态成员,如果成员内部类有静态成员,那么内部类就会在外部类之前生成,而内部类是为外部类服务的,如果在外部类之前生成就可能会脱离掌控(不懂的话看这篇文章中的例子:https://blog.csdn.net/sinat_31311947/article/details/58588704)
- 实例化:
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
- 必须先实例化外部类,再通过外部类对象实例化成员内部类
- 优点:
1)可以访问外部类的私有成员
2)用内部类定义在外部类中不可访问的数学,这样就在外部类中实现了比外部类的private还要小的访问权限
2. 局部内部类
- 即在外部类的方法中定义的内部类,与局部变量类似,并不是外部类的成员。
- 局部内部类在方法外是无法访问到的,但它的实例可以从方法中返回,并且实例在不再被引用之前会一直存在。
- 局部内部类可以访问所在方法的局部变量、方法参数等,但只能访问声明为final的方法局部变量和方法参数等。
3. 匿名内部类
- 即没有类名的局部内部类
- 特点:
- 匿名内部类不能有构造器(没有类名,肯定无法声明构造器)
- 匿名内部类必须继承一个类或实现一个接口,指定给new的类型为匿名类的超类型,匿名类不能有显示的extends或implements关键字,也不能有任何修饰符
- 匿名内部类和成员内部类、局部内部类一样,也不能声明静态成员
- 一般用于要继承或实现的接口只有一个抽象方法的场景,如监听器
4. 静态内部类
- 声明时用static修饰的内部类,定义在外部类中,任何方法外
- 静态内部类与前三种内部类不同,静态内部类不会持有外部类当前对象的引用,所以在静态内部类中无法访问外部类的非静态成员,即:静态内部类不依赖与外部类
- 因此,静态内部类中可以定义静态或非静态的成员
静态内部类的对象可以直接生成:
Outer.Inner in = new Outer.Inner();
而不需要通过生成外部类对象来生成