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

Почему статическое поле должно быть доступно статическим способом?

public enum MyUnits
{
    MILLSECONDS(1, "milliseconds"), SECONDS(2, "seconds"),MINUTES(3,"minutes"), HOURS(4, "hours");

    private MyUnits(int quantity, String units)
    {
        this.quantity = quantity;
        this.units = units;
    }

    private int quantity;
    private  String units;

 public String toString() 
 {
    return (quantity + " " + units);
 }

 public static void main(String[] args) 
 {
    for (MyUnits m : MyUnits.values())
    {
        System.out.println(m.MILLSECONDS);
        System.out.println(m.SECONDS);
        System.out.println(m.MINUTES);
        System.out.println(m.HOURS);
    }
 }
}

Это относится к сообщению.. не может отвечать или комментировать любой созданный новый. Почему мой

System.out.println(m.MILLSECONDS);

Предоставление предупреждений. Статическое поле MyUnits.MILLSECONDS должно быть доступно статическим способом? Спасибо.

4b9b3361

Ответ 1

Потому что, когда вы обращаетесь к статическому полю, вы должны сделать это в классе (или в этом случае перечислении). Как и в

MyUnits.MILLISECONDS;

Не для экземпляра, как в

m.MILLISECONDS;

Изменить. Чтобы решить вопрос о том, почему: В Java, когда вы объявляете что-то как static, вы говорите, что он является членом класса, а не объекта (следовательно, почему единственный). Поэтому не имеет смысла обращаться к нему на объект, поскольку этот конкретный элемент данных связан с классом.

Ответ 2

На самом деле есть веская причина:
Нестатический доступ не всегда работает по причине двусмысленности.

Предположим, что у нас есть два класса: A и B, причем последний является подклассом A, со статическими полями с тем же именем:

public class A {
    public static String VALUE = "Aaa";
}

public class B extends A {
    public static String VALUE = "Bbb";
}

Прямой доступ к статической переменной:

A.VALUE (="Aaa")
B.VALUE (="Bbb")

Косвенный доступ с использованием экземпляра (дает предупреждение компилятору о том, что VALUE следует статически обращаться):

new B().VALUE (="Bbb")

До сих пор, так хорошо, компилятор может угадать, какую статическую переменную использовать, то, что на суперклассе как-то еще далеко, кажется логичным.

Теперь, когда это становится сложно: интерфейсы могут также иметь статические переменные.

public interface C {
    public static String VALUE = "Ccc";
}

public interface D {
    public static String VALUE = "Ddd";
}

Позвольте удалить статическую переменную из B и наблюдать следующие ситуации:

  • B implements C, D
  • B extends A implements C
  • B extends A implements C, D
  • B extends A implements C где A implements D
  • B extends A implements C где C extends D
  • ...

Утверждение new B().VALUE теперь неоднозначно, поскольку компилятор не может решить, какая статическая переменная имела в виду, и сообщит об этом как об ошибке:

ошибка: ссылка на VALUE неоднозначна
переменная VALUE в C и переменная VALUE в D соответствуют

И именно по этой причине статические переменные должны быть доступны статическим образом.

Ответ 3

Потому что... it (MILLISECONDS) является статическим полем (скрывается в перечислении, но тем, чем оно является)... однако оно вызывается на экземпляр данного типа (но см. ниже как это на самом деле не истинно 1).

javac будет "принимать", но это действительно должно быть MyUnits.MILLISECONDS (или не префикс в применимой области).

1 На самом деле, javac "переписывает" код в предпочтительную форму - если m оказался null, он не будет бросать NPE во время выполнения - это никогда фактически вызывается на экземпляр).

Счастливое кодирование.


Я не вижу, как заголовок вопроса подходит для остальных:-) Более точные и специализированные заголовки увеличивают вероятность того, что вопрос/ответы могут принести пользу другим программистам.