在Java中使用相同的内部类名和对象名

时间:2012-10-17 09:25:44

标签: java inner-classes static-classes

在下面的代码片段中,可能看起来它应该发出一些编译错误,但它不会:

class Outer {
    public static class Inner {
        static String obj = "Inner";
    }

    static Optional Inner = new Optional();
    //The (inner) class name and the object name are same.
}

class Optional {
    String obj = "Optional";
}

public class Main {

    public static void main(String[] args) {
        System.out.println(Outer.Inner.obj);
        //Refers to the string inside the optional class
    }
}

Outer内部有一个名为Inner的静态类。此外,它声明了类Optionalstatic Optional Inner = new Optional();

的对象(静态)

此对象和类名(在类Outer内)与Inner相同。该程序显示OptionalOuter.Inner.obj中唯一的表达式main()预计会显示Inner但不会显示Optional。然而,实际输出是Optional Inner类的情况。

显示static Optional Inner1 = new Optional(); 的一种方法是将对象名称更改为其他名称。

Inner

在显示的输出中,似乎对类型名称(类{{1}})选择了对象名称(或变量),因为它们具有相同的名称。这里应用了什么确切的案例?

3 个答案:

答案 0 :(得分:14)

Java语言规范的

Paragraph 6.4.2提供了有关在这种情况下适用的规则的一些信息。

  

一个简单的名称可能出现在上下文中,它可能被解释为变量,类型或包的名称。在这些情况下,§6.5的规则指定将优先选择变量,并且将优先选择类型与包。因此,有时可能无法通过其简单名称引用可见类型或包声明。我们说这样的声明是模糊的

这是指段6.5 Determining the Meaning of a Name,它详细解释了规则。

在您的示例中,Outer.Inner可以引用名为Inner的嵌套类的类型,或静态成员变量Inner。规则说将在类型上选择变量。

答案 1 :(得分:3)

实际上,班级名称是Outer $ Inner。

内部类本质上是Java 1.1中引入的一个hack。 JVM实际上没有内部类的任何概念,因此编译器必须提供它。编译器在 B的“外部”生成 class A,但是在相同的中,然后添加合成 访问者/构造函数,以允许A访问它。

查看以下帖子:

Java inner class visibility puzzle

答案 2 :(得分:2)

想想内部类实际上有自己的.java文件。 这将使你明白为什么它选择Inner类的变量。