12

For various business reasons I want to hold some static IDs in one of my classes. They were originally int but I wanted to change them to Integer so I could do an equals on them (ie MY_ID.equals(..) which avoids NPEs)

When I change them to Integer I get errors in my switch statement. The docs say that Integer should be ok within Switches.

To quote

[Switch] also works with enumerated types (discussed in Enum Types), the String class, and a few special classes that wrap certain primitive types: Character, Byte, Short, and Integer (discussed in Numbers and Strings).

In my code below if i is a int then it compiles. When it is an Integer it doesnt saying that a constant expression is required. I have tried doing .intValue() but this doesnt work either.

Am I being really stupid? Or completely misreading the docs?

private static final Integer i = 1;

@Test
public void test() {
    switch(mObj.getId()){
        case i: //do something
        default: //do something default
    }

}

Thanks for any pointers here. For the time being I am keeping them as int and doing new Integer(myint).equals(...)

RNJ
  • 15,272
  • 18
  • 86
  • 131
  • 2
    I'll suggest you to use enums. They're really appropriate for this case. – Denys Séguret Sep 26 '12 at 14:22
  • yes I agree @dystroy. These IDs are matching ids in the database which is why we are using this. I suppose we could use enums though... – RNJ Sep 26 '12 at 14:24
  • I also use enums matched in DB, there is no problem. enums are really powerful in java now. – Denys Séguret Sep 26 '12 at 14:27
  • I just want to clarify that primitive types, like int, cannot throw Null Pointer Exceptions (NPEs) in Java, only object references can. So using int should still be a viable option. – Scott Sep 26 '12 at 14:28

6 Answers6

10

Change your constant to primitive type:

private static final int i = 1;

and you'll be fine. switch can only work with primitives, enum values and (since Java 7) strings. Few tips:

  • new Integer(myint).equals(...) might be superflous. If at least one of the variables is primitive, just do: myint == .... equals() is only needed when comparing to Integer wrappers.

  • Prefer Integer.valueOf(myInt) instead of new Integer(myInt) - and rely on autoboxing whenever possible.

  • Constant are typically written using capital case in Java, so static final int I = 1.

Anup Kumar Gupta
  • 361
  • 5
  • 14
Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • 1
    To be precise: the `switch` variable can be char, byte, short, integer, enum and String (and corresponding Object). But the `case` values must be constants, i.e. a primitive type, enum value or compile-time String. – Julien Kronegg Jul 28 '17 at 20:45
  • what if you must use it like in this code: public class SwitchOca { public static void main(String[] args) { final String x = "0"; final String y = new String("0"); switch(x) { case y: System.out.println("error ..."); break; case "2": System.out.println("primitive ..."); break; } } } – Francesco Dassisis Apr 06 '21 at 15:30
3

Switch require constant expressions in the case statements or enum constants. A constant expression is:

an expression denoting a value of primitive type or a String that does not complete abruptly

So Integers don't qualify. In your case, you can either use an int or an enum (which would make sense if your IDs are known at compile time).

The only place where you can use a boxed type (for example an Integer) is in the switch expression:

switch(Integer.valueOf(1)) {
    case 1: //
}
assylias
  • 321,522
  • 82
  • 660
  • 783
  • 2
    To quote the docs linked in my questions `It also works with enumerated types (discussed in Enum Types), the String class, and a few special classes that wrap certain primitive types: Character, Byte, Short, and Integer (discussed in Numbers and Strings).` Am I misunderstanding what it is saying? – RNJ Sep 26 '12 at 14:25
  • 2
    @RNJ That only applies to the expression in `switch(expression)`, not to the case statements. – assylias Sep 26 '12 at 14:26
  • Though I find it interesting that the Integer isn't autoboxed to int in the case statement. I would expect that, but I have never tried it. Even with the compile time constant, i is final, so the compiler should know it will always be 1, but I suppose autoboxing isn't done until runtime. (not arguing with you, just surprised) – varikin Sep 26 '12 at 14:27
3

Now that java offers enums, we usually do it like this :

public enum MyKey {
   i,
   j
}

...

switch(mObj.getId()){
    case i: //do something
    default: //do something default
}
Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
1

because I was looking at this...

The accepted answer says that:

switch can only work with primitives, enum values and (since Java 7) strings

However,

14.11 The switch Statement

outlines the JavaSE7 documentation for switch that shows:

The type of the Expression must be char, byte, short, int, Character, Byte, Short, Integer, String, or an enum type (§8.9), or a compile-time error occurs.

I just wanted to clarify for future surfers.

  • To be precise: the `switch` variable can be char, byte, short, integer, enum and String (and corresponding Object). But the `case` values must be constants, i.e. a primitive type, enum value or compile-time String. – Julien Kronegg Jul 28 '17 at 20:50
0

You must use a constant value in a switch statement.

switch(mObj.getId()){
    case 5: //do something
    default: //do something default
}
Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
gsjava
  • 131
  • 4
0

In the code shown 'i' is an object pointer, not a constant expression.

Tyler Durden
  • 11,156
  • 9
  • 64
  • 126
  • 2
    I'm sorry, I didn't want to offend you or sound rude. I just meant that what is called *pointer* in C/C++ is named *reference* in Java (sort-of). Check out [1](http://programmers.stackexchange.com/questions/141834), [2](http://stackoverflow.com/questions/92001), [3](http://stackoverflow.com/questions/9185462), [4](http://stackoverflow.com/questions/8080617) and [5](http://stackoverflow.com/questions/5174725). It's just a naming convention used among Java developers. – Tomasz Nurkiewicz Sep 26 '12 at 15:41