【问题标题】:Using an inner class name and an object name same in Java在 Java 中使用相同的内部类名和对象名
【发布时间】:2012-10-07 12:34:12
【问题描述】:

在下面的代码 sn-p 中,大概它应该发出一些编译错误,但它没有:

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 的静态类。此外,它声明了Optional (static Optional Inner = new Optional();) 类的对象(静态)

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

显示Inner 的一种方法是将对象名称更改为其他名称。

static Optional Inner1 = new Optional();

从它显示的输出中,似乎对象名称(或变量)被选择而不是类型名称(类Inner),因为它们具有相同的名称。此处应用的具体情况是什么?

【问题讨论】:

    标签: java inner-classes static-classes


    【解决方案1】:

    其实类名是Outer$Inner。

    内部类本质上是 Java 1.1 中引入的一种 hack。 JVM 实际上并没有任何内部类的概念,因此编译器不得不拒绝它。编译器生成 class B "outside" of class A,但是在同一个package中,然后添加synthetic accessors/constructors 以允许A 访问它。

    查看以下帖子:

    Java inner class visibility puzzle

    【讨论】:

    • 这确实是一个很好的答案,这里没有问到一个问题。
    【解决方案2】:

    想想内部类其实也有自己的.java文件。 这将使您清楚为什么它选择变量而不是 Inner 类。

    【讨论】:

      【解决方案3】:

      Java 语言规范的Paragraph 6.4.2 提供了有关适用于这种情况的规则的一些信息。

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-07-13
        • 1970-01-01
        • 1970-01-01
        • 2015-02-21
        • 2014-12-22
        • 2021-02-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多