Неоднозначный вызов из статического контекста в 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);
}
}
Ответы
Ответ 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);
}
}
Вышеприведенный код компилируется.