Why doesn't the switch expression allow long, float, double or boolean values in Java? why is only int (and those that are automatoically promoted to int) allowed?
- 291,719
- 55
- 540
- 600
- 5,129
- 7
- 43
- 52
-
13switch exists for boolean, it is called `if ... else` – Nicolas Feb 28 '11 at 12:18
-
1Due to the precision problem , i think they are not allowed. – Dead Programmer Feb 28 '11 at 12:25
-
@saravanan I didn't like any of the answer here: have you seen this post: [**Question about switch{} case in C?**](http://stackoverflow.com/questions/5179822/question-about-switch-case-in-c) – Grijesh Chauhan Mar 03 '13 at 08:31
-
Closely related to, but not quite a duplicate of http://stackoverflow.com/questions/2676210/why-cant-your-switch-statement-data-type-be-long-java – Raedwald Aug 12 '14 at 11:50
4 Answers
Float and double would be awkward to use reliably even if they were possible - don't forget that performing exact equality matches on float/double is usually a bad idea anyway, due to the nature of the representation.
For Boolean values, why not just use if to start with?
I can't remember ever wanting to switch on any of these types, to be honest. Do you have a particular use case in mind?
- 1,335,956
- 823
- 8,931
- 9,049
-
2I could see a use case for `float` or `double` for version information. `1.1` will always be `1.1` if you don't do any calculations. Even Java uses this trick to display version information sometimes. But I guess we'll have to byte the bullit and compare against an actual object instance representing a `Version` - or use `String` comparison from Java 7 onwards of course. – Maarten Bodewes May 12 '14 at 16:26
-
5@owlstead: 1.1 isn't a valid `float` or `double` number. You can have a literal which will convert to the *closest* `float` or `double`, but neither can precisely-represent 1.1. Did you actually mean version 1.100000000000000088817841970012523233890533447265625 (`double`) or version 1.10000002384185791015625 (`float`)? – Jon Skeet May 12 '14 at 16:28
-
Would that matter? I presume that if you parse a String then you will get either of the numbers. But I can see where it could go wrong if you mix floats and doubles. So probably the Java devs where right to leave it out. Anyway, since 1.7 there is the `String` switch which does not have these issues. Using a `double` or `float` for a version is a hack anyway. – Maarten Bodewes May 12 '14 at 16:56
-
3@owlstead: It matters because it's fundamentally an inappropriate type to use. Also, what do you do for more specific versions? If you want 1.1.1 for example? That clearly can't be represented as a `float` or `double`. Even with just major/minor, you have odd things - version 1.10 (the 11th minor version in major version 1) would be equal to 1.1. How is that useful? Using `float` or `double` for a version number is just *wrong* in my view. – Jon Skeet May 12 '14 at 16:59
-
I agree, but I see it used in quite a few API's - even Oracle ones. And switching on version nubmers is certainly a *use case*. But as said, it's a hack, and hacks should be avoided - I would consider it wrong as well. So maybe this is an additional reason to avoid the hack. There must be a Java puzzler somewhere in this :) – Maarten Bodewes May 12 '14 at 17:03
-
1@owlstead: I would certainly *hate* to see a language feature introduced because it would help in situations where an API had been badly designed. Ick, ick, ick. – Jon Skeet May 12 '14 at 17:04
-
@JonSkeet, I prefer switch over if-else because in switch, a jump table is created. So switch has a performance edge and it works slightly faster than if-else. – Confuse Mar 22 '15 at 14:56
-
@Aryan: I focus on correctness first - and floating point equality is hardly ever appropriate, so it makes sense that it isn't available in switch statements. It's not even clear that a jump table would be sensibly possible for a float... – Jon Skeet Mar 22 '15 at 15:16
-
@JonSkeet, actually I was talking about general switch working, not specifically focusing on floating point variables. – Confuse Mar 22 '15 at 15:25
-
@Aryan: Then it's not clear how it's related to this question/answer. And I wouldn't even prefer switch "in general" - I prefer whichever is most readable for the situation. – Jon Skeet Mar 22 '15 at 15:31
-
I was talking about this question which you asked in your answer - "I can't remember ever wanting to switch on any of these types, to be honest. Do you have a particular use case in mind?". – Confuse Mar 22 '15 at 15:32
-
@Aryan: Well that's specifically for float/double/boolean, as per the original question. Which of them were your referring to? – Jon Skeet Mar 22 '15 at 15:47
-
I was referring to other types too like int/string etc. I am sorry but I didn't notice that you were talking specifically about float/double/boolean. – Confuse Mar 22 '15 at 15:51
-
An example were you would want to switch case a boolean will be if you want to Switch on ranges of integers. For example: `int x = 20; switch(true){ case x >0 && x <10 : ...; case x >10 && x <20: ... ; case x >20 && x <30: ... ; ....}` . This is really useful. – Yaki Klein Apr 23 '15 at 17:26
-
@YakiKlein: That's moving way beyond just "switching on different types" though - that's now switching on *expressions* rather than constants. That's not what the question was about. – Jon Skeet Apr 23 '15 at 17:31
-
-
You can use enum in a switch statement and Java 7 will add String AFAIK. The switch statement comes from C where only int's were allowed and implementing other types is more complicated.
Floating point numbers are not a good candiates for switch as exact comparison is often broken by rounding errors. e.g. 0.11 - 0.1 == 0.01 is false.
switch on boolean is not much use as a plain if statement would be simpler
if(a) {
} else {
}
would not be simpler with
switch(a) {
case true:
break;
case false:
break;
}
BTW: I would use switch(long) if it were available, but its not. Its a rare use case for me any way.
- 513,304
- 74
- 731
- 1,106
For float and double float and double I'd assume they have omitted it for the same reasons as why it's a bad idea to compare them using ==.
For boolean, it may simply be because it would correspond to an if statement anyway. Remember that you can only have constants in the case-expressions, so the cases would always correspond to if (someBool) and if (!someBool).
For long I don't have an explanation. Seems to me that such feature perhaps should have been included when designing the language.
- 399,198
- 105
- 792
- 807
-
@aiodbe But would it be worth changing the language to support `switch` on `long`. That's a surprising amount of work for spectacularly little gain. (I guess why there wasn't `switch` on `long` in 1.0 is that it wouldn't fit with the existing pair of `switch` ops, so would either have to add two more pointless ops or provide a separate mechanism for compiling this case. And JDK 1.00 needed to ship to Netscape in six weeks.) – Tom Hawtin - tackline Feb 28 '11 at 12:31
-
Ah, I agree completely. I guess I was trying to say "seems like a reasonable good idea to include". I know that the current ops are tied to `ints` so yes, it would probably involve a change in the bytecode set which is a huge thing to begin with. Updated the answer slighly. – aioobe Feb 28 '11 at 12:56
Usually switch-case structure is used when executing some operations based on a state variable. There an int has more than enough options. Boolean has only two so a normal if is usually good enough. Doubles and floats aren't really that accurate to be used in this fashion.
Frankly I can't imagine a use case for this stuff, did you have some practical problem in mind with this question?
- 1,455
- 10
- 8