Java内部类

内部类是什么?

作为包的成员的类被称为顶级类。一个类可以在另一个类中声明。 这种类型的类称为内部类。
如果在另一个类中声明的类被显式或隐式声明为static,它被称为嵌套类,而不是内部类。
包含内部类的类称为封闭类或外部类。

示例

下面的代码声明一个内部类。

class Outer {
  public class Inner {
    // Members of the Inner class go here
  }
  // Other members of the Outer class go here 
}

Outer类是一个顶级类。Inner类是一个内部类。 它是外类的成员。Outer类是Inner类的封闭(外部)类。内部类可以是另一个内部类的封闭类。 内部类的嵌套层次没有限制。

内部类的实例只能存在于其封闭类的实例中。

使用内部类的优点

以下是内部类的一些优点:

  • 在使用它们的其他类中定义类。
  • 提供了一个额外的命名空间来管理类结构。
  • 一些设计模式使用内部类更容易实现。
  • 实现回调机制使用内部类是优雅和方便的。它有助于在Java中实现闭包。

访问局部变量的限制

下面的代码演示了访问局部内部类中的局部变量的规则。
main()方法声明两个局部变量:xy。 这两个变量都是被声明为 final。变量x在被初始化之后不能改变,变量y也不能被改变,因为它被声明为final

public class Main {
  public static void main(String... args) {
    final int x = 1;
    final int y = 2;

    class LocalInner {
      void print() {
        System.out.println("x = " + x);
        System.out.println("y = " + y);
      }
    }
    /*
     * Uncomment the following statement will make the variable x no longer
     * an effectively final variable and the LocalIneer class will not compile.
     */
    // x = 100;

    LocalInner li = new LocalInner();
    li.print();
  }
}

上面的代码生成以下结果。

x = 1
y = 2

内部类和继承

内部类可以继承另一个内部类,顶级类或其封闭类。

class A {
  public class B {
  }

  public class C extends B {
  }

  public class D extends A {
  }
}

class E extends A {
  public class F extends B {
  }
}

内部类中没有静态成员

Java中的关键字static使一个构造成为一个顶层结构。因此,不能为内部类声明任何静态成员(字段,方法或初始化器)。
允许在内部类中有作为编译时常量的静态字段。

class A {
  public class B {
    public final static int DAYS_IN_A_WEEK = 7; // OK
    public final String str = new String("Hello");
  }
}

生成的内部类的类文件

每个内部类都被编译成一个单独的类文件。成员内部类和静态内部类的类文件名格式如下:

<outer-class-name>$<member-or-static-inner-class-name>

本地内部类的类文件名的格式如下:

<outer-class-name>$<a-number><local-inner-class-name>

匿名类的类文件名的格式如下:

<outer-class-name>$<a-number>

类文件名中的<a-number>是从1开始顺序生成的数字,以避免任何名称冲突。

静态上下文中的内部类

可以在静态上下文中定义一个内部类,例如静态方法或静态初始化器。所有静态字段成员都可以访问这样的内部类。

class Outer {
  static int k = 1;
  int m = 2;

  public static void staticMethod() {
    // Class Inner is defined in a static context
    class Inner {
      int j = k; // OK. Referencing static field k
      // int n = m; // An error. Referencing non-static field m
    }
  }
}

上一篇:Java不可变对象

下一篇:Java内部类类型

关注微信小程序
程序员编程王-随时随地学编程

扫描二维码
程序员编程王

扫一扫关注最新编程教程