Подтвердить что ты не робот

Неоднозначный вызов из статического контекста в Java

Основной метод пытается получить доступ к var, но приводит к неоднозначному вызову. Зачем? Экземпляр переменной var в Base1 в любом случае недоступен (видимо?) Из статического контекста.

  class Base1 {
      int var;
  }

  interface Base2 {
      public static final int var = 0;
  }

  class Test extends Base1 implements Base2 { 
      public static void main(String args[]) {
          System.out.println("var:" + var); 
      }
  }
4b9b3361

Ответ 1

Правило JLS для двусмысленности доступа к полю -

Если идентификатор называет несколько доступных полей элемента (§6.6) в type T, тогда доступ к полю неоднозначен и ошибка времени компиляции имеет место.

И по вопросу доступности

Элемент (класс, интерфейс, поле или метод) ссылочного типа или конструктор типа класса, доступен, только если тип доступный, и член или конструктор объявляется для разрешения доступа:

В нем не делается различия в том, приведет ли доступ к полю экземпляра ошибку компиляции в контексте static.

Обратите внимание, что вы могли иметь

public static void main(String args[]) {
    Test test = new Test();
    System.out.println("var:" + test.var); 
}

У вас все еще будет двусмысленность.

Ответ 2

Чтобы сделать это однозначно, поместите имя интерфейса в качестве квалификационного префикса:

class Test extends Base1 implements Base2 { 

      public static void main(String args[]) {
          System.out.println("var:" + Base2.var); 
      }
 }

Ответ 3

Вначале на первом шаге компилятор будет искать переменную var в классе, который вы расширяете, и интерфейс, который вы реализуете. Так как он находит переменную в обоих местах на втором шаге, она показывает двусмысленность.

Ответ 4

Статический и нестационарный контексты не определяют, к каким переменным разрешен доступ

Модификаторы доступа - это те, которые фактически управляют этим...

измените модификатор доступа для var в Base1 до private, и неопределенность исчезнет, ​​хотя это может быть не так, как вы хотите, чтобы он был сформирован, но доступ к modfiers на самом деле диктует ссылку на переменные экземпляра, чем статический статический контекст.

class Base1 {
    private int var;
    //static int var=5;
}

interface Base2 {
    public static final int var = 0;
}

class ambiguousNonStaticCall extends Base1 implements Base2 { 
    public static void main(String args[]) {
        System.out.println("var:" + var); 
    }
}

Вышеприведенный код компилируется.