Q: Error while trying to find workaround to Java's requirement that cases in switch statements must be final I'm trying to find a workaround to Java's requirement that cases in switch statements must be final. So far, my attempts have failed, and I am unsure as to why this is happening. I would prefer to use a switch statement rather than an if/else unless absolutely necessary.
My goal is to have a switch statement with a case that varies depending on the value of a non-final variable. Java requires that the case be constant. 
To get around this requirement, I have tried creating final variables with the value of non-final variables. This way, the final variables can be used as cases while still having the value of a non-final variable.
Assigning a local or an instance variable's value to a final variable causes a compiler error (method test2 for local variables, test3 for instance variables). Why does this occur? 
On the other hand, assigning a final variable to a literal constant works perfectly (method test1). 
Is there any possible workaround to Java's restriction?
class Main {
  private int instance = 0;
  public Main(int i){
      instance = i;
  }
  public void test1(int num){
      final int FINAL = 3;
      switch(num){
          case FINAL:
          System.out.println(FINAL);
          break;
          default:
          System.out.println("nothing");
      }
  }
  // methods test2 and test3 did not compile
  public void test2(int num){
      int locVar = 3;
      final int FINAL = locVar;
      switch(num){
          case FINAL:
          System.out.println(FINAL); // line 20
          break;
          default:
          System.out.println("nothing");
      }
  }
  public void test3(int num){
      final int FINAL = instance;
      switch(num){
          case FINAL:
          System.out.println(FINAL); // line 30
          break;
          default:
          System.out.println("nothing");
      }
  }
  public static void main(String[] args) {
    Main m = new Main(3); // instance variable named int instance = 3
    m.test1(3);
    // m.test2(3);
    // m.test3(3);
  }
}

Expected output (if this were to work perfectly):
3
3
3

Error produced: constant expression required at lines 20 and 30

A: 
I'm trying to find a workaround to Java's requirement that cases in switch statements must be final

Such efforts are a wild goose chase. There is no workaround of this requirement, assuming you wish your case labels to refer to a "variable".
According to JLS 14.11:

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

So, it is not even a requirement that the case labels are final: it is that they have to be constant expressions, of which constant variables ("a final variable of primitive type or type String that is initialized with a constant expression") are merely one kind.
A key point about constant variables is that is final is necessary, but not sufficient.
The reason why switch cases must be constant is that the compiler generates a table of jumps (either tableswitch or lookupswitch): in order to do this, it must know all the possible jumps at compile time.
Some languages support non-constant cases in switches (e.g. golang, or Kotlin's when), but Java does not.
You have to use an alternative control structure (e.g. if/else) if you want to avoid the requirement of constant case labels.
