7

在下面的 java 示例中,任何人都可以准确解释为什么程序的输出是 "Orange" 吗?(这是一道面试题)

public class Finder {
  public static void main(String[] args){
    System.out.println(X.Y.Z);
  }
}

class X {
  static W Y = new W();
  static class Y {
    static String Z ="Apple";
  }
}

class W {
  String Z = "Orange";
}
4

2 回答 2

10

变量 Y 掩盖了 Y 类型。参见JLS

6.4.2. 遮蔽

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

限定名称 XYZ 根据以下方式解析:

6.5.2. 上下文模糊名称的重新分类

...

如果名称在“。”的左侧。被重新分类为 TypeName,则:

  • 如果标识符是由 TypeName 表示的类型的方法或字段的名称,则此 AmbiguousName 被重新分类为 ExpressionName。

  • 否则,如果 Identifier 是由 TypeName 表示的类型的成员类型的名称,则将此 AmbiguousName 重新分类为 TypeName。

  • 否则,会发生编译时错误。

由于类型和变量的正常命名约定,这在实践中不太可能发生。

于 2012-12-25T02:43:19.870 回答
3

您正在使用名为 Y 的 W 的静态实例隐藏类 Y。类 Y 仍然存在并且可以使用。尝试:

System.out.println(X.Y.Z);
System.out.println((new X.Y()).Z);

输出应该是

Orange
Apple

另请参阅:Java 字段隐藏

于 2012-12-25T02:29:15.823 回答