目录
一、概念
二、分类
1、实例内部类
2、静态内部类
3、本地内部类
4、匿名内部类
内部类:在Java中,可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类。

注意:
(1)定义在class类名{}花括号外部的,即使是在同一个文件里,都不能称为内部类
(2)内部类和外部类共用一个java源文件,但是经过编译之后,内部类会形成单独的字节码文件
在外部类中,内部类定义的位置与外部类成员所处的位置相同,因此也被称为成员内部类。而实例内部类就是未被static修饰的成员内部类。
注意:
(1)实例内部类中不能直接定义静态成员变量

如果在数据类型前加个final修饰,使其成为一个常量,则可以通过编译:

(2)实例内部类中不能定义静态成员方法
因为实例内部类没有被static修饰,在外部类加载的时候并不会加载它,所以它里面不能有静态方法或者静态变量。
(3)实例内部类对象必须在先有外部类对象前提下才能创建

(4)在实例内部类可以访问外部类成员变量(静态成员变量也可以访问),当外部类成员变量名和实例内部类成员变量名重名时,优先访问实例内部类成员变量:
class ExternalClass{public String name = "张三";public int age = 18;public static String school = "B站大学";class InnerClass{public String name = "李四";public int score = 99;public InnerClass(String name) {this.name = name;System.out.println("实例内部类的构造方法");}public void func(){System.out.println("实例内部类的成员方法");System.out.println(this.name);System.out.println(name);System.out.println(this.score);System.out.println(age);System.out.println(school);}}
}
public class TestDemo {public static void main(String[] args) {ExternalClass out = new ExternalClass();ExternalClass.InnerClass innerClass1 = out.new InnerClass("张三");innerClass1.func();}
执行结果:

如果要调用外部类变量名,则需要通过外部类类名来调用:

(5)外部类中,不能直接访问实例内部类成员,如果要访问必须先创建内部类对象。


注意:
(1)静态内部类中只能直接访问外部类的静态成员,访问非静态成员需要先创建一个外部类对象
当我们创建一个外部类对象后,就可以通过外部类对象来访问外部类的非静态成员了:

也可以给构造函数传参时传一个外部类对象来访问:

(2)创建静态内部类对象时,不需要先创建外部类对象

因为静态内部类是被static修饰的,它会随着外部类的加载而加载,所以它不依赖于对象,可以直接通过外部类类名创建。
定义在外部类的方法体或者{}中,该内部类只能在其定义的位置使用,一般使用的非常少(也叫局部内部类)。
注意:
(1)本地内部类只能在所定义的方法体内部使用
(2)不能把public、static等修饰符修饰
(3)也会生成独立的字节码文件,命名格式为:外部类名$内部类名.class
(4)几乎不会使用本地内部类
匿名内部类是局部内部类的一种简化形式,本质上是一个对象~
如果某个对象在整个程序中只需要使用一次,那么就可以使用匿名内部类~
匿名内部类一般是作为参数或者返回值来使用~
例如:使用匿名内部类创建Thread子类对象
public class Demo {public static void main(String[] args) {Thread t = new Thread(){@Overridepublic void run() {System.out.println("hello");}};}
}