定义 在 Java 中,内部类是一种特殊的类,它定义在另一个类的内部
内部类的分类:成员内部类(静态、非静态)vs 局部内部类(方法内、代码块内、构造器内)
成员内部类 成员内部类可以是静态的或非静态的。静态内部类不能访问外部类的非静态成员,但可以访问外部类的静态成员。非静态内部类可以访问外部类的所有成员。
下面是一个示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package com.base.learn;public class OuterClass { private int x = 10 ; static int y = 20 ; static class StaticInnerClass { public void print () { System.out.println("Static Inner Class: y = " + y); } } class InnerClass { public void print () { System.out.println("Inner Class: x = " + x + ", y = " + y); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package com.base.learn;public class Main { public static void main (String[] args) { OuterClass.StaticInnerClass staticInner = new OuterClass .StaticInnerClass(); staticInner.print(); OuterClass outer = new OuterClass (); OuterClass.InnerClass inner = outer.new InnerClass (); inner.print(); } }
输出
1 2 Static Inner Class: y = 20 Inner Class: x = 10 , y = 20
内部类常用于实现回调
局部内部类 在 Java 中,局部内部类是一种特殊的内部类,它定义在方法内部。局部内部类只能在定义它的方法内部访问,不能在方法外部访问。局部内部类也可以访问外部类的所有成员,包括私有成员
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package com.base.learn;public class OuterClass2 { private int x = 10 ; static int y = 20 ; public void method () { class LocalInnerClass { public void print () { System.out.println("Local Inner Class: x = " + x + ", y = " + y); } } LocalInnerClass inner = new LocalInnerClass (); inner.print(); } }
1 2 3 4 5 6 7 8 9 package com.base.learn;public class Main2 { public static void main (String[] args) { OuterClass2 outer = new OuterClass2 (); outer.method(); } }
输出
1 Local Inner Class: x = 10 , y = 20
局部内部类常用于在方法内部创建类,并且只在方法内部使用
有个注意的点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package com.base.learn;public class OuterClass2 { private int x = 10 ; static int y = 20 ; public void method () { int num = 10 ; class LocalInnerClass { public void print () { System.out.println("Local Inner Class: x = " + x + ", y = " + y); } } LocalInnerClass inner = new LocalInnerClass (); inner.print(); } }
匿名内部类 在 Java 中,匿名内部类(Anonymous Inner Class)是没有名称的内部类,通常用于简化代码结构,特别是在需要创建只有一次使用的小类时。匿名内部类通常用于实现接口或继承类,并且可以在方法内部、代码块内部或者表达式中定义。
匿名内部类的使用场景 实现接口 :当只需要实现接口的某些方法时,而不想为此创建一个单独的类。继承类 :继承一个类并重写它的方法,且不希望创建一个新的子类文件。简化代码 :适用于仅在某一处需要特定功能或逻辑的场景,不必定义额外的类文件。语法格式 匿名内部类通常以一种表达式的形式存在,具体语法如下:
继承类的匿名内部类 :实现接口的匿名内部类 :实现接口的匿名内部类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class Test { public static void main (String[] args) { Runnable runnable = new Runnable () { @Override public void run () { System.out.println("匿名内部类实现了 Runnable 接口" ); } }; Thread thread = new Thread (runnable); thread.start(); } }
继承类的匿名内部类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class Test { public static void main (String[] args) { Animal animal = new Animal () { @Override public void makeSound () { System.out.println("匿名内部类继承了 Animal 类并重写方法" ); } }; animal.makeSound(); } } class Animal { public void makeSound () { System.out.println("Animal 的声音" ); } }
匿名内部类的限制 无法拥有构造器 :因为匿名内部类没有类名,因此不能定义构造器。只能访问局部的 final或effectively final变量 :如果匿名内部类要访问外部的局部变量,这些变量必须是 final 或 effectively final(实际上不会被修改的变量)。不能声明静态成员 :匿名内部类不能包含静态方法或静态变量(除非是常量)。匿名内部类的简洁性和临时性使它非常适合处理简单的实现需求,如事件监听器、回调函数等。