Что происходит, когда Static Variable имеет то же имя, что и Static Class в Java?

В приведенном ниже примере java может кто-нибудь объяснить, почему вывод программы "Оранжевый"? (это вопрос интервью)

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

Ответ 1

Переменная Y скрывает тип Y. См. JLS:

6.4.2. Сокрытие

Простое имя может возникать в контекстах, где это может быть потенциально интерпретируется как имя переменной, типа или пакета. В этих ситуации, правила § 6.5 указывают, что будет выбрана переменная в предпочтении к типу, и что тип будет выбран в предпочтении к пакету. Таким образом, иногда бывает невозможно ссылаться на видимый тип или объявление пакета через его простое имя. Мы говорим, что такая декларация скрыта.

Квалифицированное имя X.Y.Z разрешено в соответствии с:

6.5.2. Реклассификация контекстуально неоднозначных имен

...

Если имя слева от "." переклассифицируется как TypeName, а затем:

  • Если Идентификатор является именем метода или поля типа, обозначенного TypeName, это AmbiguousName реклассифицируется как ExpressionName.

  • В противном случае, если Идентификатор является именем типа-члена типа, обозначенного TypeName, это AmbiguousName реклассифицируется как TypeName.

  • В противном случае возникает ошибка времени компиляции.

Это вряд ли произойдет на практике из-за нормальных соглашений об именах для типов и переменных.

Ответ 2

Вы скрываете класс Y со статическим экземпляром W с именем Y. Класс Y все еще существует и может использоваться. Попробуйте:

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

Выход должен быть

Orange
Apple

Также смотрите: Скрытие Java-полей