На самом деле есть веская причина:
Нестатический доступ не всегда работает по причинам неоднозначности .
Предположим, у нас есть два класса, 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 в C и переменная VALUE в D совпадают
Именно поэтому статические переменные должны быть доступны статическим способом.