Java 中的内部类有四种主要类型:成员内部类、局部内部类、匿名内部类和静态内部类。
1. 成员内部类
成员内部类是定义在另一个类中的非静态类,也被称为“非静态内部类”。它依赖于外部类的实例,因此只能通过外部类的对象来访问。
特点:
-
成员内部类可以访问外部类的所有成员变量和方法(包括私有成员)。
-
成员内部类可以直接访问外部类对象的成员变量,因为它持有外部类对象的引用。
-
需要通过外部类的实例创建成员内部类的实例。
注意点:
(1)该类是外部类的一个成员,可以外部类的所有成员任何属性和成员方法;
(2)成员内部类拥有与外部类同名的成员变量时,会被隐藏。如果要访问外部类中的成员,需要以下形式访问:外部类.this.成员变量 或 外部类.this.成员方法;
(3)在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问;
示例代码:
public class OuterClass { private String outerField = "Outer class field"; // 成员内部类 public class InnerClass { public void display() { System.out.println("Outer field: " + outerField); // 访问外部类的成员 } } public void createInnerClass() { InnerClass inner = new InnerClass(); // 创建内部类的实例 inner.display(); } public static void main(String[] args) { OuterClass outer = new OuterClass(); outer.createInnerClass(); } }
2. 局部内部类
局部内部类是定义在一个方法、构造器或代码块中的内部类。局部内部类只能在它所在的范围内使用。
特点:
-
局部内部类的作用范围仅限于它所定义的方法或代码块内。
-
局部内部类可以访问外部类的成员变量,也可以访问方法的局部变量,但局部变量必须是
final
或“有效final
”的。 -
它不能被
public
、protected
或private
等访问修饰符修饰,因为它的作用域是局部的。
注意点:
(1)局部内部类是定义在一个方法或者一个作用域里面的类
(2)局部内部类就像是方法里面的一个局部变量一样,不能被public、protected、private以及static修饰符的。
示例代码:
public class OuterClass { private String outerField = "Outer class field"; public void createLocalInnerClass() { String localVar = "Local variable"; // 局部内部类 class LocalInnerClass { public void display() { System.out.println("Outer field: " + outerField); // 访问外部类的成员 System.out.println("Local variable: " + localVar); // 访问局部变量 } } LocalInnerClass localInner = new LocalInnerClass(); localInner.display(); } public static void main(String[] args) { OuterClass outer = new OuterClass(); outer.createLocalInnerClass(); } }
3. 匿名内部类
匿名内部类是没有名字的内部类,通常用于简化代码,直接创建某个类或接口的子类或实现类的实例。匿名内部类经常用于实现接口或继承类的瞬时对象。
特点:
-
匿名内部类没有类名,直接在实例化时定义。
-
它可以用来实现接口或继承父类,但只能实现一个接口或继承一个类。
-
由于匿名内部类是瞬时的,通常用于一次性使用的场景。
注意点:
(1)匿名内部类不能有访问修饰符和static修饰符的
(2)匿名内部类是唯一一种没有构造器的类
示例代码:
interface Greet { void sayHello(); } public class OuterClass { public void createAnonymousInnerClass() { // 使用匿名内部类实现接口 Greet greet = new Greet() { @Override public void sayHello() { System.out.println("Hello from anonymous inner class!"); } }; greet.sayHello(); } public static void main(String[] args) { OuterClass outer = new OuterClass(); outer.createAnonymousInnerClass(); } }
4. 静态内部类
静态内部类是使用static
修饰的内部类。它与成员内部类的最大区别在于,它不依赖于外部类的实例,可以直接通过外部类访问,类似于静态方法。
特点:
-
静态内部类不能访问外部类的非静态成员(因为它没有外部类实例的引用)。
-
它可以访问外部类的静态成员。
-
可以通过外部类直接创建静态内部类的实例,而不需要外部类的实例。
注意点:
(1)静态内部类不需要依赖于外部类,这一点和类的静态成员属性类似
(2)不能使用外部类的非static成员变量或者方法
示例代码:
public class OuterClass { private static String staticOuterField = "Static outer class field"; // 静态内部类 public static class StaticInnerClass { public void display() { System.out.println("Static outer field: " + staticOuterField); // 访问外部类的静态成员 } } public static void main(String[] args) { OuterClass.StaticInnerClass inner = new OuterClass.StaticInnerClass(); // 创建静态内部类的实例 inner.display(); } }
总结
-
成员内部类:依赖于外部类的实例,可以访问外部类的所有成员。
-
局部内部类:定义在方法或代码块中,仅在该方法或块内有效,可以访问外部类的成员和方法中的局部变量。
-
匿名内部类:没有名字的类,通常用于一次性实现接口或类,简化代码。
-
静态内部类:不依赖于外部类的实例,可以访问外部类的静态成员。