简体   繁体   中英

Compile Time Constant Usage in Switch Case Java

The rules of case usage say:

  1. The case expression must evaluate to a Compile Time Constant .

  2. case(t) expression must have same type as that of switch(t), where t is the type (String).

If i run this code :

public static void main(String[] args) {
    final String s=new String("abc");
    switch(s)
    {
       case (s):System.out.println("hi");
    }

}

It gives Compile-error as: "case expression must be a constant expression" On the other hand if i try it with final String s="abc"; , it works fine.

As per my knowledge, String s=new String("abc") is a reference to a String object located on heap. And s itself is a compile-time constant.

Does it mean that final String s=new String("abc"); isn't compile time constant?

In Java SE 7 and later, you can use a String object in the switch statement's expression.

You can only use constant expressions in the cases and no variables.

creating a String with a constructor isn't considered a constant.

Use this,

    String s= new String("abc");
    final String lm = "abc";

    switch(s)
    {
       case lm:
           case "abc": //This is more precise as per the comments
           System.out.println("hi");
           break;
    }

As per the documentation

A variable of primitive type or type String, that is final and initialized with a compile-time constant expression (§15.28), is called a constant variable

The problem is your code final String s= new String("abc"); does not initializes a constant variable.

It doesn't consider new String() to be a constant (even though String is immutable).

Try this:

public static void main(String[] args)
{
    final String s = "abc";
    switch (s)
    {
        case (s):
            System.out.println("hi");
    }
}

Edit: I guess your switch (s) is a typo, there wouldn't be much point in that.

Also, if you're using constants in your switch statements like that, it's probably going to be clearer to extract them as a constant field, eg private static final String s = "abc"; . And even clearer if you were to use an enum instead of strings, but I realise that isn't always possible.

The thing is you can change the value of variable S anywhere in the switch so this probably can execute all the cases . So it gives "case expression must be a constant expression" error and in case if variable is final then its value cant be changed.

EDIT

In case you need to have Compile time constants and final variables are considered to be Runtime constants. As final variables can be delayed initialized and the compiler cannot determine.

The problem is that your trying to switch and test the case variable s . Which, is throwing the error. "case expression must be a constant expression" . This has nothing to do with s per se... but using s as the case variable. Understand?

Here's a sample using the same variable that works properly.

private void switchTest() {
    final String s = new String("abc");
    switch (s) {
        case "abc":
            System.out.println("This works fine... woohoo.");
            break;
        default:
            System.out.println("Do something default.");
    }

}

what about an int or other primitive datatype as compile time constant for switch statement?

public class MainClass{ 
    public static void main(String[] argv){ 
        final int a = 1;
        final int b; 
        b = 2; 
        int x = 0; 
        switch (x) { 
            case a: // ok 
            case b: // compiler error 
        } 
    } 
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM