1

I have this piece of code that aims to translate a string from a Spinner item to an integer for use in another part of the application. This worked well when I had constant strings in the switch case, but later on I wanted to move those hard-coded strings into the Strings.xml resource to separate them from the logic. This is where I wound up in trouble, since Java wants the strings to be constant.

I tried to make the strings final, but it didn't make any difference. So my question is, would it somehow be possible to make the strings from a resource constant to make them usable in a switch case like the one in the code snippet below?

public int getPositionFromText(String text) {
    // The string representations of the different score methods.
    String[] scoreOptions = getResources().getStringArray(R.array.scoreOptions);
    final String three = scoreOptions[0];
    final String four = scoreOptions[1];
    final String five = scoreOptions[2];
    switch(text) {
        case three:
            return 0;
        case four:
            return 1;
        case five:
            return 2;
        default:
            return 0;
    }

}
Filip Hedman
  • 407
  • 2
  • 12

2 Answers2

2

There is no way around the "constant expression required" compilation error. The Java Language Specification requires that the switch expressions are compile-time constant expressions.

My advice would be to construct a HashMap. Use the resource constant values as the keys, and the scores / positions as the values.


Here is what the JLS says on the subject:

JLS §14.11:

Every case label has a case constant, which is either a constant expression or the name of an enum constant.

JLS §15.28:

A constant expression is an expression denoting a value of primitive type or a String that does not complete abruptly and is composed using only the following:

  • Literals of primitive type and literals of type String.
  • The additive operators + and -.
  • Simple names that refer to constant variables .
  • Qualified names of the form <TypeName> . <Identifier> that refer to constant variables.
  • ....

JLS §14.12.4:

A constant variable is a final variable of primitive type or type String that is initialized with a constant expression.


Why?

  1. The implementation of switch statement for primitive types uses JVM instructions that require literal constants ... in the code.

  2. In the String and enum cases, the switching is performed using code / data structures that the compiler / runtime system constructs bases on the cases. If the cases are not constant, then the compiler can't construct them.

  3. If the values of the switch constants are not constant, then the compiler cannot do proper analysis of definite assignment and reachability.

The first two could be viewed as "just" implementation details. The final point is more fundamental. Relaxing the rule would break the language.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
-2

Everything is possible

 switch(text) {
    case getString(R.string.three):
        return 0;
    case "four":
        return 1;
    case "five":
        return 2;
    default:
        return 0;
}
John Sardinha
  • 3,566
  • 6
  • 25
  • 55