2013-11-28 53 views
5

我把下面的代码从K个&乙书“SCJP Sun认证的程序员对Java 6的学习指南”:的Java内部类阴影外部类

class A { // 1 
    void m() { 
     System.out.println("outer"); 
    } 
} 

public class TestInners { 

    public static void main(String[] args) { 

     new TestInners().go(); 

    } 

    void go() { 

     new A().m(); 

     class A { // 2 
      void m() { 
       System.out.println("inner"); 
      } 
     } 

    } 

    class A { // 3 
     void m() { 
      System.out.println("middle"); 
     } 
    } 
} 

正如书中所说,这个代码打印“中间”。我推断标记为“3”的类声明隐藏了TestInners类外部标记为“1”的类。 如果这些类位于不同的包中,我可以通过用包名称对其中一个进行限定来解决含糊不清的问题。但在这种情况下,类不仅在相同的包中,而且在同一个文件中。我如何获得外部类的实例?

我看到了同样的问题here但接受的答案意味着修改代码添加一个封闭的类到整个事情。我的问题是如何使用任何类型的限定符或引用来获取实例,如果甚至可能的话。

+3

如果它们位于_any_包中,说'p',则可以使用'p.A'作为// 1和'p.TestInners.A'作为// 3。否则,我不认为有可能明确提及它们。因为你必须违反编码标准来达到这个目的(没有包的类),但实际上这不是问题。 – creichen

回答

4

假设你的类是在包com.test,所有你需要做的是使用类的完全限定名称中使用

new com.test.A().m(); 

如果你的类是在默认包,即。没有package声明,那么你是运气不好,不能访问外部A

+0

*如果这些类位于不同的包中,我可以通过用包名称对其中一个进行限定来解决含糊不清的问题* OP已经知道这一点。重新阅读这个问题:*但是在这种情况下,类不仅在同一个包中,而且在同一个文件中。我怎样才能得到外部类的实例?* –

+3

@LuiggiMendoza:我认为重点是即使它们在* same *包(和文件)中,这也是可行的。 –

+1

@OliCharlesworth,但他没有包裹。 – Domi

2

在C++中,可以通过在::前加符号来明确地定位全局作用域,但是Java没有这样的事情。所以如果你真的想要得到外部A,你必须咬下子弹并做一些其他类型的外壳,例如将其包装在另一个类或包中。

编辑:Here is another reason why

0

innner-A的对象在定义之前无法创建,所以在go()内部定义innner-A后使用new A().m();来访问内部类对象。

void go() { 

     class A { 
      void m() { 
       System.out.println("inner"); 
      } 
     } 
     new A().m(); 
    } 

要访问outer-A,您必须追加包名,在缺省包中不可能访问outer-A。