1.内部类
定义:
Java中的内部类(Inner Class)是指在一个类的内部定义的类。
使用场景:
当一个类的内部,存在一个部分需要完成的结构进行描述,而该内部结构只为外部类提供服务,那么这个内部结构就可以使用内部类(如Map中的entry内部类)
在Java中,内部类一共有以下几个分类:
1.1 实例内部类
定义在类内部方法外部且未使用static修饰的内部类
//外部类
public class SampleOuterClass {
//实例内部类
public class SampleInnerClass {
}
}
- 1.实例内部类所处的位置和外部类中的其他成员一样,同样可以使用访问限定修饰符。且外部类的访问限定修饰符和实例内部类的访问限定修饰符相互独立
- 2.外部类的任意成员(构造方法除外)都可以在实例内部类中直接访问
- 3.当外部类和内部类中存在同名成员时,优先访问内部类中的成员。如果要访问外部类中的成员需要使用
外部类类名.this.同名成员
来访问
- 4.必须先创建外部类对象,再通过外部类对象的引用来创建实例内部类对象
未创建外部类对象而直接创建内部类对象会抛出NullPointerException
异常
- 5.在外部类中访问实例内部类的成员必须先创建实例内部类对象
1.2 静态内部类
定义在类内部方法外部且使用static修饰的内部类
public class OuterClass {
public static class StaticInnerClass {
}
}
- 1.静态内部类中只能访问外部类的静态成员
- 2.创建静态内部类对象前不需要先创建外部类对象
3.在静态内部类中访问外部类的静态成员时,需要通过外部类的类名来访问。即使在静态内部类中存在同名的静态成员也不会冲突
- 4.在外部类中访问静态内部类成员的方式与访问实例内部类成员一样
1.3 局部内部类(不常用)
定义在方法内部
public class OuterClass {
public String publicNumber = "outer";
public void method(){
//局部内部类
class LocalInnerClass {
public final String publicNumber = "inner";
public void method(){
System.out.println(this.publicNumber);
System.out.println(OuterClass.this.publicNumber);
}
}
//只能在本方法内部实例化LocalInnerClass
LocalInnerClass localInnerClass = new LocalInnerClass();
localInnerClass.method();
}
}
public class Test {
public static void main(String[] args) {
OuterClass outerClass = new OuterClass();
outerClass.method();
}
}
- 1.局部内部类访问外部类成员的方式与实例内部类一样
- 2.外部类无法访问局部内部类的任何成员
- 3.局部北部类只能在本方法内部实例化
- 4.局部内部类只能使用和局部变量一样的修饰符(局部变量能使用哪些修饰符,局部内部类就只能使用这些)
1.4 匿名内部类
- 没有类名,直接实现接口或者继承类
interface IUsb{
void method();
}
public class OuterClass {
public static void main(String[] args) {
//匿名内部类
new IUsb()
{
@Override
public void method() {
System.out.println("匿名内部类");
}
};
}
}
调用重写方法的方式有两种:
- 1.直接在匿名内部类后面调用方法
interface IUsb{
void method();
}
public class OuterClass {
public static void main(String[] args) {
//匿名内部类
new IUsb()
{
@Override
public void method() {
System.out.println("匿名内部类");
}
}.method();
}
}
- 2.创建一个引用指向该匿名内部类,使用该引用调用方法
interface IUsb{
void method();
}
public class OuterClass {
public static void main(String[] args) {
//匿名内部类
IUsb iUsb = new IUsb()
{
@Override
public void method() {
System.out.println("匿名内部类");
}
};
iUsb.method();
}
}
1.5 内部类的源文件&字节码文件
所有内部类和外部类公用同一份java文件,但是在编译后内部类也会生成单独的字节码(class)文件