Search code examples
javaandroidswitch-statementcompile-time-constantconstant-expression

Static Final Ints in Switch: Why can't this be done?


I had a Switch referencing Resource Ids from R.java in a Library Project:

switch (code) {

    case R.id.code_one:
        blah();
        break;
    case R.id.code_two:
        bleh();
        break;
}

From ADT 14, R fields are no longer final, so Google suggests to change the switch into nested if's. Fair enough.

However, I wonder why this doesn't work:

final int CODE_ONE=R.id.code_one, CODE_TWO=R.id.code_two;
switch (code) {

    case CODE_ONE:
        blah();
        break;
    case CODE_TWO:
        bleh();
        break;
}

or this:

class blih {
    private final static int CODE_ONE=R.id.code_one, CODE_TWO=R.id.code_two;
    void bluh(int code) {
        switch (code) {

            case CODE_ONE:
                blah();
                break;
            case CODE_TWO:
                bleh();
                break;
        }
    }
}

All them complain with the error "Case statements must be constant expressions" ... aren't they, specially the first one? Whichever the value R.id.xxx might be, aren't I "finalizing" it into a snapshot constant?


Solution

  • Case statements must be constant expressions at compile time. If you initialize them at runtime, they are not constants.

    final does not mean "compile-time constant". It only means "can be assigned only once". This does enable the compiler to inline values at compile-time if the final value is known, allowing initialized final ints to be used in case expressions.