2011-01-31 48 views
4

所有疯狂的Java范围规则正在使我的头脑旋转,而废话无助于事情的发展。到目前为止,我所使用的所有编程语言,无论是词法范围还是近似值,都没有任何访问修饰符,即内部东西捕获外部东西,只要内部东西存在就可以访问外部东西。Java范围规则和内部类

那么,我如何理解Java中内部类的范围规则呢?他们是否可以访问在外部类中声明的变量,或者是否有一些奇怪的边缘情况需要担心,因为所有的东西都是浮动的?

+9

请(1)调低和(2)澄清你的问题。你所问的'疯狂的Java范围规则'与C++中的'词法范围'相同。你将不得不解释你的意思是“公共静态无效”的废话:这是另一个功能,它也存在于C++中。而“公共静态私人”的东西“并不存在:这仅仅是一个矛盾。 – EJP 2011-01-31 06:06:32

+1

可以肯定的是,OP来自脚本语言背景,具有真正的词法范围(例如JavaScript,Ruby),并且不重视修饰符关键字。只是说。 – ide 2011-01-31 06:11:49

回答

17

静态嵌套类酷似外部类不同之处在于它们可以访问外部类的所有成员,而不管接入限定符。它们除了外部类的任何实例之外都存在,因此需要引用实例才能访问外部类的任何实例变量或非静态方法。

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

对于内部类和访问说明符的一个很好的(也是非常详细的)讨论,您可以通读Inner Class Specification。它还描述了嵌套类如何访问外部类的成员(private)。一个温和的阅读是Nested Classes tutorial

闲谈一边:假设你有这样的阶级结构:

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,那将是没有必要的(实际上是一个错误)。

  你经常会遇到短语“静态内部类”(包括令人尴尬的,在这个答案的早期版本)。这是不正确的术语。在Java中,“内部类”特别是不嵌套的类。

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); 
} 
3

我不知道是否有帮助,但是从java tutorials

静态嵌套类

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

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

与实例方法和变量,一个内部类与它的外围类和的实例相关联具有与对象的方法和字段的直接访问。另外,因为内部类与一个实例相关联,所以它不能自己定义任何静态成员。

您应该检查the java tutorial on nested classes

0

规则内部类

  1. 通过内部类访问外部类
  2. 内部类不能由外类访问
  3. 内类成员只使用的方法和构件在类内只访问充实的信息
-1

方法范围内部分类ses: - 只能访问外部类的最终成员。