目录
一、概念
内部类:在Java中,可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类。
注意:
(1)定义在class类名{}花括号外部的,即使是在同一个文件里,都不能称为内部类
(2)内部类和外部类共用一个java源文件,但是经过编译之后,内部类会形成单独的字节码文件
二、分类
1、实例内部类
在外部类中,内部类定义的位置与外部类成员所处的位置相同,因此也被称为成员内部类。而实例内部类就是未被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)外部类中,不能直接访问实例内部类成员,如果要访问必须先创建内部类对象。
2、静态内部类

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