Причины ограничений на присвоение конечных переменных - PullRequest
0 голосов
/ 11 марта 2012
  1. Почему final переменные по умолчанию не инициализированы? Не должен ли конструктор по умолчанию инициализировать их значениями по умолчанию, если вы довольны тем, что константа является значением по умолчанию.

  2. Почему вы вообще должны их инициализировать в конструкторе? Почему вы не можете просто инициализировать их, прежде чем использовать их как другие переменные?

отл.

public class Untitled {

public final int zero;

     public static void main(String[] args)
     {
          final int a; // this works
          a = 4; // this works, but using a field doesn't
          new Untitled();
     }
}

Untitled.java:2: variable a might not have been initialized
  1. Почему вы должны инициализировать static final переменные, когда они объявлены? Почему вы не можете просто инициализировать их, прежде чем использовать их любым другим способом?

ех.

public class Untitled
{

      public final static int zero;

      public static void main(String[] args)
      {
           zero = 0;
      }
}

Untitled.java:8: cannot assign a value to final variable zero

Я задаю этот вопрос, потому что я пытаюсь найти логическую / концептуальную причину, почему это не будет работать, почему это не разрешено. Не только потому, что это не так.

Ответы [ 4 ]

3 голосов
/ 11 марта 2012

Идея переменной final состоит в том, что она устанавливается один и только один раз.

Например, final переменные, это означает, что они могут быть установлены только во время инициализации, будь то при объявлении, вконструктор или блок инициализации экземпляра.Чтобы переменная была установлена ​​в другом месте, это должно происходить в неконструкторном методе, который можно вызывать несколько раз - вот почему это запрещено.

Аналогично для static final переменных ониможет быть установлен только при объявлении или в статическом блоке инициализации.В другом месте, опять-таки, должен присутствовать метод, который можно было бы вызвать более одного раза:

public static void main(String[] args)
{
     zero = 0;
     main(null);
}

Что касается вашего первого вопроса, я предполагаю, что ошибочно не задавать final явнопеременная во избежание ошибок программиста.

1 голос
/ 11 марта 2012

В разделе Спецификация языка Java 8.3.1.2 прописаны правила для final переменных-членов:

Поле может быть объявлено final (§4.12.4). И переменные класса и экземпляра (static и не- static поля) могут быть объявлены как окончательные.

Ошибка времени компиляции, если пустая переменная класса final (§4.12.4) определенно не назначена (§16.8) инициализатором static (§8.7) класса, в котором она объявлена .

Пустая final переменная экземпляра должна быть обязательно назначена (§16.9) в конце каждого конструктора (§8.8) класса, в котором она объявлена; в противном случае возникает ошибка времени компиляции.

JLS не дает оснований почему правила такие, какие они есть. Тем не менее, это может быть связано с опытом написания Java-кода, и приведенные выше правила позволяют избежать некоторых распространенных ошибок кодирования.

0 голосов
/ 11 марта 2012

Потому что, глядя на ваш код, компилятор Java не знает, будет ли данный оператор выполняться перед другим оператором. Единственными исключениями из этого правила являются код в конструкторах и неявные конструкторы, и именно поэтому они являются единственным местом, которому могут быть назначены конечные поля.

0 голосов
/ 11 марта 2012

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

Я не очень рационально отношусь к первому вопросу.

...