Java内部类遮蔽外部类

5

我从K&B的书“SCJP Sun Certified Programmer for Java 6 Study Guide”中获得了以下代码:

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

正如书中所述,此代码将打印“middle”。我推断标记为“3”的类声明遮盖了TestInners类外部标记为“1”的类声明。 如果这些类在不同的包中,我可以通过使用包名称限定其中一个来解决歧义。但在这种情况下,这些类不仅在同一个包中,而且在同一个文件中。我怎样才能获得外部类的实例? 我在这里看到了相同的问题,但被接受的答案暗示要修改代码并添加一个封闭类到整个代码块中。我的问题是如何使用任何类型的限定符或引用获取实例,如果可能的话。

3
如果它们在任何包中,比如说 'p',则可以使用 'p.A' 来表示 //1,使用 `p.TestInners.A' 来表示 //3。否则我认为不可能显式地引用它们。由于你必须违反编码标准才能到达这一点(没有包的类),因此实际上这不是一个问题。 - creichen
3个回答

4
假设您的类在 com.test 包中,您需要做的就是使用:
new com.test.A().m();

使用类的全名来引用。

如果你的类在默认包中,也就是没有package声明,那么你将无法访问外部的A


如果这些类在不同的包中,我可以通过使用包名限定其中一个类来消除歧义。但是,在这种情况下,这些类不仅在同一个包中,而且在同一个文件中。我该如何获取外部类的实例? - Luiggi Mendoza
3
我认为重点是,即使它们在同一个包(和文件)中,这也可以正常工作。 - Oliver Charlesworth
1
@OliCharlesworth 但他没有一个包。 - Domi
@Domi:也许吧。但在实践中不应该出现这种情况。 - Oliver Charlesworth
@LuiggiMendoza //3的完全限定名是<yourpackage>.TestInners.A,因此<yourpackage>.A应该访问外部类,而你所做的调用只访问“最近”的类(按包分类)。 - LuigiEdlCarno
@LuigiEdlCarno 但是对于这个例子,类不在一个包内。我知道将类放在默认包中并不实用,但这是问题的代码。在我看来,唯一的答案应该是creichen的评论 - Luiggi Mendoza

2
在C++中,您可以使用::前缀显式地引用全局范围内的符号,但是Java没有这样的东西。因此,如果您真的想要获取外部A,则必须咬紧牙关并进行其他类型的封闭,例如将其包装在另一个类或包中。
编辑:这里有另一个原因

0

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

void go() {

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

要访问outer-A,你必须附加包名,在默认包中无法访问outer-A。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接