今天Java学习的内容是内部类。顾名思义就是定义在一个类内部的类。说实话内部类平时开发不一定会天天用但是看源码的时候经常遇到所以还是要掌握的。下面是我的学习总结。一、内部类的概念内部类定义在一个类内部的类。// 外部类 class Outer { // 内部类 class Inner { } }内部类的特点编译后生成独立的.class文件命名规则外部类名$内部类名.class内部类可以直接访问外部类的私有成员不破坏外部类的封装性内部类分为四种成员内部类、静态内部类、局部内部类、匿名内部类二、四种内部类1. 成员内部类了解位置定义在类以内、方法以外类比于实例变量。特点创建内部类对象必须依赖外部类的对象成员内部类中不能定义静态成员class Outer { private int value 10; // 成员内部类 class Inner { public void show() { // 可以直接访问外部类的私有成员 System.out.println(外部类的value: value); } } } // 创建成员内部类对象 Outer outer new Outer(); Outer.Inner inner outer.new Inner(); // 依赖外部类对象 inner.show();访问外部类的当前对象class Outer { int num 10; class Inner { int num 20; public void show() { int num 30; System.out.println(num); // 30局部变量 System.out.println(this.num); // 20内部类成员 System.out.println(Outer.this.num); // 10外部类成员 } } }2. 静态内部类了解位置定义在类以内、方法以外同时被static修饰类比于静态变量。特点可以定义实例变量也可以定义静态变量创建对象只需要依赖外部类的类名不需要外部类对象只能访问外部类的静态成员class Outer { static int staticValue 100; int instanceValue 200; // 静态内部类 static class StaticInner { static int a 10; // 可以定义静态变量 int b 20; // 也可以定义实例变量 public void show() { System.out.println(staticValue); // ✅ 可以访问外部类静态成员 // System.out.println(instanceValue); // ❌ 不能访问实例成员 } } } // 创建静态内部类对象不需要外部类对象 Outer.StaticInner inner new Outer.StaticInner(); // 访问静态内部类的静态成员 Outer.StaticInner.a 50;3. 局部内部类了解位置定义在方法内部类比于局部变量。特点只能在定义它的方法内部创建对象局部内部类的方法可以访问定义它的方法内部的局部变量但该变量必须被final修饰JDK8会自动加class Outer { public void outerMethod() { int localVar 100; // 局部变量JDK8默认是effectively final // 局部内部类 class LocalInner { public void show() { System.out.println(localVar); // 可以访问JDK8自动加final } } // 必须在方法内部创建对象 LocalInner inner new LocalInner(); inner.show(); } }语法糖JDK8及以上版本如果检测到局部变量被局部内部类访问编译器会默认加上final这叫“语法糖”。4. 匿名内部类重点概念一个特殊的局部内部类定义和创建对象一起完成。特点必须继承一个类或实现一个接口只能创建一个对象优点减少代码量编程思路连贯缺点可读性较低语法接口名 引用名 new 接口名() { // 实现接口中的方法 };示例1实现接口interface IA { void m1(); void m2(); } public class Test { public static void main(String[] args) { // 匿名内部类实现接口 IA ia new IA() { Override public void m1() { System.out.println(实现m1方法); } Override public void m2() { System.out.println(实现m2方法); } }; ia.m1(); ia.m2(); } }示例2继承类class MyClass { public void method() { System.out.println(父类中的method方法); } } public class Test { public static void main(String[] args) { // 匿名内部类继承MyClass并重写方法 MyClass mc new MyClass() { Override public void method() { System.out.println(子类覆盖后的方法); } }; mc.method(); // 子类覆盖后的方法 } }示例3作为方法参数常见用法interface OnClickListener { void onClick(); } class Button { public void setOnClickListener(OnClickListener listener) { // 模拟点击 listener.onClick(); } } public class Test { public static void main(String[] args) { Button btn new Button(); // 匿名内部类作为参数 btn.setOnClickListener(new OnClickListener() { Override public void onClick() { System.out.println(按钮被点击了); } }); } }三、四种内部类对比类型位置创建对象方式能否访问外部类静态成员能否访问外部类实例成员能否定义静态成员成员内部类类内、方法外依赖外部类对象✅✅❌静态内部类类内、方法外有staticnew Outer.Inner()✅❌✅局部内部类方法内在方法内创建✅✅需要对象❌匿名内部类方法内常用和定义一起完成✅✅❌四、我踩过的坑坑1成员内部类创建对象语法错误Outer.Inner inner new Outer.Inner(); // ❌ 错误解决成员内部类需要依赖外部类对象Outer outer new Outer(); Outer.Inner inner outer.new Inner(); // ✅坑2静态内部类中访问外部类实例成员class Outer { int value 10; static class StaticInner { public void show() { System.out.println(value); // ❌ 编译报错 } } }解决静态内部类只能访问外部类的静态成员把value改成static或者通过对象访问。坑3局部内部类访问的局部变量没有加finalJDK7及以下void method() { int x 10; class Inner { void show() { System.out.println(x); // JDK7及以下会报错 } } }解决JDK7及以下需要手动加finalJDK8会自动处理。坑4匿名内部类语法记不住// 标准写法 接口/父类 变量名 new 接口/父类() { // 实现方法 };解决多写几遍记住这个模板。五、匿名内部类的实际应用场景场景1线程Runnablenew Thread(new Runnable() { Override public void run() { System.out.println(线程执行中...); } }).start();场景2排序ComparatorListString list new ArrayList(); Collections.sort(list, new ComparatorString() { Override public int compare(String o1, String o2) { return o1.length() - o2.length(); } });场景3GUI事件监听button.addActionListener(new ActionListener() { Override public void actionPerformed(ActionEvent e) { System.out.println(按钮被点击); } });六、小练习用匿名内部类实现一个简单的打招呼功能// 打招呼接口 interface Greeting { void sayHello(); } public class Test { public static void main(String[] args) { // 中文打招呼 Greeting chinese new Greeting() { Override public void sayHello() { System.out.println(你好世界); } }; // 英文打招呼 Greeting english new Greeting() { Override public void sayHello() { System.out.println(Hello, World!); } }; chinese.sayHello(); english.sayHello(); } }总结今天学的内部类虽然有点绕但总结下来就是类型一句话总结成员内部类依赖外部类对象创建不能有静态成员静态内部类不依赖外部类对象只能访问外部类静态成员局部内部类定义在方法内只能在该方法内使用匿名内部类定义和创建一起完成常用于接口回调面试高频题内部类有哪几种成员内部类和静态内部类的区别为什么局部内部类访问的局部变量需要是final的匿名内部类的优缺点我接下来的任务把课堂上的内部类案例都敲一遍特别是匿名内部类的各种用法加上注释再做一些练习题巩固。如果你也在学Java欢迎一起交流我们明天继续