4

所有疯狂的 Java 作用域规则都让我头晕目眩,而public static void废话也无济于事。到目前为止,我使用的所有编程语言要么使用词法作用域,要么使用它的一些近似值,而没有任何访问修饰符,即内部东西捕获外部东西,只要内部东西存在,就可以访问外部东西。

那么如何理解 Java 中内部类的作用域规则呢?他们是否可以访问在外部类中声明的变量,或者是否有一些奇怪的边缘情况我必须担心,因为所有公共静态私有的东西都在浮动?

4

6 回答 6

17

静态嵌套类1与外部类完全相同,只是它们可以访问外部类的所有成员,而不管访问限定符如何。它们存在于外部类的任何实例之外,因此需要对实例的引用才能访问外部类的任何实例变量或非静态方法。

非静态嵌套类(称为内部类)仅在外部类实例的上下文中存在。构造时,它们会this自动生成第二个字段,您可以使用语法从内部类中访问该字段Outer.this。内部类的每个实例都包含在外部类的单个实例中。同样,静态嵌套类的所有访问权限都适用于内部类。但是由于他们已经有一个可用的外部类的实例,他们可以自动访问外部类的实例变量和方法。

有关内部类和访问说明符的精彩(非常详细)的讨论,您可以通读Inner Class Specification。除其他外,它还描述了嵌套类如何访问private其外部类的成员。更温和的阅读是嵌套类教程

题外话:假设你有这样的类结构:

public class O {
    public O() { ... }

    public class I { // an inner class
        public I() { ... }
        ...
    }
    ...
}

并且您创建了一个实例O

O outer = new O();

现在假设您要创建一个O.I. 您不能只使用new O.I(),因为新实例I需要由O. 为此,Java 提供了以下语法:

O.I inner = outer.new O.I();

然后inner将其第二个this字段设置为引用outer

请注意,这种“限定new运算符”语法仅用于内部类;I如果是static嵌套类,那将是不必要的(实际上是一个错误) 。

1 您经常会遇到“静态内部类”一词(令人尴尬的是,在此答案的早期版本中)。这是不正确的术语。在 Java 中,“内部类”特别是非static嵌套类。

于 2011-01-31T06:03:21.183 回答
3

你必须区分:

  • 静态内部类可以访问其声明之外的所有静态成员。
  • 实例内部类可以访问其声明之外的所有类成员,以及声明它们的函数中的最终字段。

请记住,非静态内部类也有一个带有外部类实例的隐藏变量,以访问那里的成员。并且当内部类被实例化时,所有引用的最终字段(因此它们必须是最终的)被复制到其他隐藏成员变量中的内部类中。

例子:

public void doStuff(final int a, int b) {
    final int c; // Can be referenced
    int d;       // Cannot be referenced, not final

    executer.execute( new Runnable() {
        public void run() {
            System.out.println("a: "+a+"  c: "+c);
        }
    }

    b++; // Not final, not referencable
    System.out.println(b);
}
于 2011-01-31T06:00:48.417 回答
3

我不知道它是否有帮助,但来自java 教程

静态嵌套类

与类方法和变量一样,静态嵌套类与其外部类相关联。和静态类方法一样,静态嵌套类不能直接引用在其封闭类中定义的实例变量或方法——它只能通过对象引用来使用它们。注意:静态嵌套类与其外部类(和其他类)的实例成员交互,就像任何其他顶级类一样。实际上,静态嵌套类在行为上是一个顶级类,为了方便打包,它已经嵌套在另一个顶级类中。

内部类[非静态嵌套类?]

与实例方法和变量一样,内部类与其封闭类的实例相关联,并且可以直接访问该对象的方法和字段。此外,由于内部类与实例相关联,它本身不能定义任何静态成员。

您应该查看有关嵌套类的 java 教程

于 2011-01-31T06:05:26.550 回答
3

Java内部类的规则

  1. 在 Java 中,可以在另一个类中定义一个类,这样的类称为嵌套类或内部类。
  2. 内部类有 3 种类型 Instance Inner 类、静态内部类和匿名内部类
  3. 如果内部类被声明为实例内部类,那么它可以访问外部封闭类的所有成员,包括私有成员
  4. 如果内部类被声明为静态,那么它只能访问外部类的静态成员(包括私有静态成员)。但它不能访问实例成员
  5. 考虑到在外部类和实例内部类中都定义了一个变量 x,那么从内部类访问变量的一般形式是this.x针对内部 x 和OuterClassname.this.x外部 x。
  6. 您还可以在任何方法或任何其他块中定义内部类
  7. 从外部类外部实例化内部类的一般形式是 Outer.Inner ob = new Outer.new Inner();
  8. 从外部类外部实例化内部类的一般形式是(如果内部类声明为静态) Outer.Inner ob = new Outer.Inner();
  9. 可以使用任何访问修饰符关键字声明内部类
  10. 如果内部类被声明为私有,则它不能从外部类外部实例化。同样在这种情况下,即使您有对象引用并且即使私有内部类的成员被声明为公共,您也不能从外部类外部访问内部类的成员。
  11. 如果 Inner 类被声明为实例内部类,那么它也可以通过通用语句访问外部类的超类成员 Outer.super.variable; Outer.super.method(params);
于 2018-04-12T18:36:28.840 回答
0

内部类规则

  1. 内部类访问的外部类
  2. 外部类不能访问内部类
  3. 内部类成员只使用方法,类内成员只访问完整信息
于 2013-08-21T00:17:07.560 回答
-2

方法作用域内部类:- 只能访问外部类的最终成员。

于 2015-08-07T16:43:06.287 回答