Крайна константа не се приема в случай на превключване

Бих искал да знам разликата между 2-те декларации в метод 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