До недавнего времени я был почти на 100% убеждён в том, что прекрасно понимаю сущность констант в языке программирования Java. Так было, пока я не наткнулся на один из примеров, который был представлен в JLS (Java Language Specification). Он немного поверг меня в ступор, и я не могу разобраться с этим вопросом вплоть до текущего момента.
Наверное, я не сильно ошибусь, если скажу, что типичных констант в языке программирования Java нет вообще (во всяком случае, если смотреть с колокольни какого-нибудь С++). Даже ключевое слово const
, которое зарезервировано с незапамятных времён, но до сих пор не используется, как бы ненавязчиво намекает нам об этом (не уверен, но вроде бы это было сделано для того, чтобы сохранить обратную совместимость с С++ в том случае, если константы всё-таки будут введены в язык).
В качестве некоторого общепринятого суррогата используется связка модификаторов static final
в процессе декларирования переменной. Если я правильно понимаю, то именно такие переменные и считаются константами с точки зрения программистского сообщества ЯП Java. В то же время, если заглянуть на просторах JLS в параграф, который посвящён инициализации классов и интерфейсов, мы можем наткнуться на один интересный момент. Небольшая выдержка оттуда:
Example 12.4.1-3. Interface Initialization Does Not Initialize Superinterfaces
interface I {
int i = 1, ii = Test.out("ii", 2);
}
interface J extends I {
int j = Test.out("j", 3), jj = Test.out("jj", 4);
}
interface K extends J {
int k = Test.out("k", 5);
}
class Test {
public static void main(String[] args) {
System.out.println(J.i);
System.out.println(K.j);
}
static int out(String s, int i) {
System.out.println(s + "=" + i);
return i;
}
}
This program produces the output:
1
j=3
jj=4
3
The reference to J.i is to a field that is a constant variable (§4.12.4); therefore, it does not cause I to be initialized (§13.4.9).
The reference to K.j is a reference to a field actually declared in interface J that is not a constant variable; this causes initialization of the fields of interface J, but not those of its superinterface I, nor those of interface K.
Despite the fact that the name K is used to refer to field j of interface J, interface K is not initialized.
И вот этот момент мне совершенно непонятен! В интерфейсах все поля неявным образом помечаются как public static final
(другими они и не могут быть), что мы и видим в приведённом примере. Все поля имеют совершенно одинаковый набор модификаторов, но при этом, поле J.i
называют константной переменной, а K.j
константой уже не является, если верить примеру, который приведён в JLS.
Что же такое константа с точки зрения JLS? Неужели это не абсолютно все статические финализированные поля? Правильно ли я понял, что при присваивании значения через его возврат функцией, мы уже не можем считать поле константой?
С точки зрения JLS:
A constant variable is a final variable of primitive type or type String that is initialized with a constant expression
То есть константа - это final
переменная (причем речь не только о static
и не только о полях) примитивного типа или типа String
, которая проинициализирована константным выражением
Вызов метода константным выражением не является, поэтому K.j
- это не константа
Виртуальный выделенный сервер (VDS) становится отличным выбором
Хочу протестить свой кодЛично я ошибок не нахожу(почти), другие люди находят
Подскажите пожалуйста, как добавить иконки к пунктам меню, которые расположены в системном трее (в данном случае к пункту "Профиль")В официальном...