I appreciate that anything that can be done by a switch statment, can be done by an if else statement.
But are there stylistic rules for when one should use the switch rather than if else statment.
I appreciate that anything that can be done by a switch statment, can be done by an if else statement.
But are there stylistic rules for when one should use the switch rather than if else statment.
Well, switch feels "lighter" in many cases than an if/else if ladder, in my opinion. Basically you don't have that much syntax with braces and parentheses in the way of your code. That being said, switch inherits C's syntax. That means you have break and only a single scope for variables unless you introduce new blocks.
Still, the compiler is able to optimize switch statements into a lookup table and perform compile-time checking for literals when dealing with enumerations. So, I'd suggest that it's usually preferable to use switch over if/else if if you're dealing with numeric or enum types.
Switch has one advantage when it comes to clarity:
switch (i) {
case 1:
// do something
break;
case 2:
case 4:
// do something
break;
case 5:
// do something
break;
}
If the code for 2 and 4 are identical, it may be more clear than:
if ( i == 1 ) {
// do something
}
if ( (i == 2) || (i == 4) ) {
// do something
}
if ( (i == 5 ) {
// do something
}
It's also easier for you (or another programmer) to split out the 2 and 4 cases.
I use switch statements for enums, it is more readable that a if else if else if statements. However, you should try to avoid such checks in a OO design.
You use a switch statement when you are switching on different values of primitive / enum / wrapper types. (And not all primitive / wrapper types, just the supported ones - byte, short, char, int).
If/else handles the rest.
For instance, it is more aesthetically pleasing to say:
int i = getValueOfI();
switch (i) {
case 1:
// do something
break;
case 2:
// do something
break;
etc.
than
if (i == 1) {
} else if (i == 2) {
}...
for a large number of cases. But you can't switch on Strings, or function values, or complex conditions, so if you need to do any of that then you're stuck with if/else.
Personnally, i use to find both constructs a little too procedural. Although it may considered as OO extermism, I use to use a Map containing instances of an internal interface for each cases of the if. It allows better code isolation, i think. However, to trully reply your question, I only use switchs when I have cases that really overlap (the, I don't use break statements). Unfortunatly, it's really not a maintainable code block.
I'd suggest the simple rule:
Always use a switch when you have at least 2 options to differentiate between, when the data type is usable for a switch and when all options have constant values.
There are three good reasons. One, in most cases switch is faster than an if/else cascade. Two, it makes the intention of the code clearer. Three, the oh so bad forgotten break dilemma is a lesser evil than huge if/else cascades that accidentally break because somebody forgot an else.
Java VMs actually support two different sorts of switch: the tableswitch and the lookupswitch instruction. The tableswitch gets generated by the compiler if all case constants lie in a narrow range, otherwise it generates a lookupswitch. For large switch statements with many cases the tableswitch is more efficient than the lookupswitch. The lookupswitch is usually implemented by some form of binary search.
There are two factors for me:
Readability and whether you want to decide something using ranges of values or conditions (in switch statements you can only use a single integer or enumerated value).
first of all, the switch statement has to be useable. If the switch is based on the value of a variable, then it can be used. If it is based on a complex AND/OR/NOT boolean expression that varies for each condition, then you can't use it at all.
That being said, if it is applicable, and there are at least 2 cases, then I use the switch. It is more easily extendible, easier to read and check.
Switch and enums.
If the enum value you are testing can legitimately be null for any reason, putting it into switch statement will generate a NullPointerException. Without looking at the byte code it's kind of baffling that it would do so.
The explanation: enums are syntactic sugar introduced in 1.5. Switch statement still works with good-ole ints, but the values the it uses are ordinals assigned to enum. In order to get the ordinal, the enum value MUST be non-null.
if statement, on the other hand, would be happy to accept null for an enum value and just fail the test without NPE.
Maybe a bit offtopic, but if I answered just the question in the title, then I would say that you shouldn't use switch in all situations where cases represent states of some object. State pattern is much prettier solution in those cases.
As with other languages such as C or C++, switch statements are useful when you want to compare a given variable with a list of possible values and perform an action depending on these values. It is terser than if else statements.
Deciding whether to use if-then-else statements or a switch statement is based on readability and the expression that the statement is testing. An if-then-else statement can test expressions based on ranges of values or conditions, whereas a switch statement tests expressions based only on a single integer, enumerated value, or String object. [The switch Statement - Oracle]
Switch has two relevant disadvantages:
Often switch is a sign for poor OO design, because you'd better use polymorphism.
The only possible advantage of switch is, that it is more readable. But is
switch (i) {
case 1:
// do something
break;
case 2:
// do something
break;
}
more readable than this:
if (i == 1)
//do something
else if (i == 2)
// do something else
I'd say: no! And you wouldn't have the disadvantages of switch.
My suggestion: Try to avoid switch.