Окончательная константа не принимается в случае переключения

Я хотел бы знать разницу между двумя объявлениями внутри метода add(), как показано ниже.

final int c;
c = 20;

а также

final int c = 20;

Я думаю, что обе переменные являются конечными, для которых я не могу переназначать новые значения. Вот метод, который по-разному обрабатывает вышеуказанные объявления.

void add() {
        final int a = 30;
        final int b = 10;
        final int c;
        c = 20;

        switch (a) {
        case b + c:
            System.out.println("In case b+c");
            break;

        default:
            break;
        }

    }

Вышеупомянутый метод вообще не компилируется, жалуясь, что

требуется постоянное выражение, случай b+c

Если переменная c объявлена ​​и инициализирована в одной строке, например final int c = 30;. Оно работает.


person srk    schedule 05.05.2014    source источник
comment
Посмотрите на этот en.m.wikipedia.org/wiki/Final_(Java) как указано в ссылке, final используется, когда переменная не будет изменена. Вы объявляете переменную, но не устанавливаете ее значение... Затем ниже вы устанавливаете ее значение... Вы не можете этого сделать..   -  person Savlon    schedule 05.05.2014
comment
Оба эквивалентны (я думаю) в том смысле, что вы можете присвоить c один раз. Если вы хотите сохранить логику вашего коммутатора, выполните final int d = b+c; и случай d: в вашем коммутаторе.   -  person schmop    schedule 05.05.2014
comment
Дубликат: stackoverflow.com/ вопросы/16255270/   -  person fastcodejava    schedule 10.05.2014


Ответы (5)


JLS #4.12.4 определяет < em>постоянные переменные как (выделено мной):

Переменная примитивного типа или типа String, которая является окончательной и инициализируется константным выражением времени компиляции, называется константной переменной.

В вашем случае final int c = 20; является постоянной переменной, а final int c; c = 20; - нет.

person assylias    schedule 05.05.2014

Компилятор Java заменяет идентификатор final его значением, если он объявлен и инициализирован в одном (одном) операторе, в противном случае идентификатор сохраняется как есть и инициализируется jvm во время выполнения для переменной blank final. Вы можете увидеть это, открыв файл class. Оператор switch разрешает использовать переменную final, но не blank, в качестве значения case.

final int a = 20; // concrete final variable
switch(a){}
#=> gets changed by compiler as the following:--
switch(20){}

final int a; // blank final variable
a = 20;
switch(a){}
#=> compiler leave it for jvm to initialize 
switch(a){}
person Alok Anand    schedule 05.05.2014

Поскольку вы инициализируете и объявляете это отдельно, вы получаете эту ошибку, делайте это одновременно, и это работает

person Khyathi36    schedule 10.05.2014

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

void add() {
    final int a = 30;
    final int b = 10;
    final int c;
    c = 20;
    final int cmp=b+c;
    switch (a) {
    case cmp:
        System.out.println("In case b+c");
        break;
    default:
        break;
    }
}

Теперь это будет хорошо работать для вас,

person Afzal Ahmad    schedule 05.05.2014
comment
Ошибка компиляции: case expressions must be constant expressions. Взгляните на принятый ответ, здесь принимается выражение с конечными переменными. Неконечная переменная не принимается. - person Joffrey; 05.05.2014

Вы должны инициализировать локальную переменную перед использованием.

person niiraj874u    schedule 05.05.2014
comment
Он инициализируется перед использованием. Проблема в том, что он не инициализирован во время объявления. - person Paul Tomblin; 05.05.2014