Страницы

Поиск по вопросам

четверг, 27 февраля 2020 г.

Что в Java является константой, а что - нет?

#java #переменные #интерфейс #константа


До недавнего времени я был почти на 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? Неужели это не абсолютно все статические
финализированные поля? Правильно ли я понял, что при присваивании значения через его
возврат функцией, мы уже не можем считать поле константой?
    


Ответы

Ответ 1



С точки зрения 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 - это не константа

Комментариев нет:

Отправить комментарий