Understanding switch behaviour - java

Consider the following code
int x = 1
switch(x) {
case 1:
System.out.println("1");
case 2:
System.out.println("2");
default:
System.out.println("no value found");
}
it prints
1
2
no value found
as expected because there is no break in each case statement
my doubt is that how execution goes to each case statement if there is no break in first one
because x is not equal 2 then also its execute case 2 block
but i understood default one because without break program continue its execution and execute the default statement

This is a remnant of the C programming language. In C switch is little more than a little syntactic sugar over a goto depending on the expression value and thus execution simply jumps to the appropriate case and continues from there. The labels in between are exactly that: labels. They are jump targets but don't affect control flow otherwise and from the compiler's point of view there is nothing in a label that merits a jump elsewhere (except there is INTERCAL's COMEFROM somewhere). So you have to put an explicit break after every case where you don't want to fall through to other options.
Java more or less inherited those semantics while eschewing some of the crazier C idioms.
C# on the other hand goes a bit further by disallowing fall-through entirely on non-empty case labels.
In my opinion though, this was a bit of a design error. Fall-through by default may be much easier to implement in the compiler (because you don't have to add a goto to the end of the switch and it aligns very nicely with how things actually work underneath), but in my experience there are vastly more programming errors by accidentally using fall-through than by accidentally not using it.
The most severe design error in my eyes is including the switch statement with all its weirdness in modern languages.

For reasons that are inherited from C++, execution naturally proceeds until the end of switch or a break. There is no test against cases as they are encountered.

switch is fall through. You need to add break before each next case unless you want that.
switch (x) {
case 1:
System.out.println("1");
break;
case 2:
System.out.println("2");
break;
default:
System.out.println("no value found");
}

It's to do with how it's compiled and optimization.
It's why a switch is preferable to a bunch of chained if statements.

From java doc:
The break statements are necessary because without them, statements in
switch blocks fall through: All statements after the matching case
label are executed in sequence, regardless of the expression of
subsequent case labels, until a break statement is encountered

The switch statement is not like an if-then-else statement. switch statement has multiple execution path.
The Documentation states:
Control flow continues with the first statement following the switch
block. The break statements are necessary because without them,
statements in switch blocks fall through: All statements after the
matching case label are executed in sequence, regardless of the
expression of subsequent case labels, until a break statement is
encountered.

The switch statement is an abstraction of a branch table, and a branch table also has an implicit fall-through and requires an additional jump instruction to avoid it. Read this SO answer as well.
As per JLS 14.11:
The body of a switch statement is known as a switch block.
If one of the case constants is equal to the value of the expression, then we say that the case matches, and all statements after the matching case label in the switch block, if any, are executed in sequence.
If all these statements complete normally, or if there are no statements after the matching case label, then the entire switch statement completes normally.

It's correct behaviour. "default" doesn't mean all possible answers. It means all answers without these written in cases.
int x=1
switch(x)
{
default:
System.out.println("no value found");
case 1:
System.out.println("1");
case 2:
System.out.println("2");
}
will print
1
2
won't print
no value found
1
2
when using breaks; statements and default value there is called only one "branch" for each value

Each break statement terminates the enclosing switch statement. All statements after the matching case label are executed in sequence, regardless of the expression of subsequent case labels, until a break statement is encountered.
You can use if-then-else just, the overhead of testing is increases..., which is avoided in switch-case, but break is necessary for proper execution...

Related

Switch Case Function in Java, How does this code work? [duplicate]

This question already has answers here:
Why do we need break after case statements?
(17 answers)
Closed last month.
I was trying to work on Multiple Choices for my java foundations and came up with this Code.
I am have experience with switch cases and all but this is the first time, I encounter this problem!
Can someone explain me how can that argument go into those cases like in 1, 2, 3 or 4 when the number itself is different?
public static void main(String[] args) {
switch (5) {
default:
case 1:System.out.println("1");
case 2:System.out.println("2");
case 3:System.out.println("3");break;
case 4:System.out.println("4");
}
}
The Output was:-
1
2
3
There are various flavours of switch. This one is the basic switch statement, the only one that was in java since the beginning. This simple flavour 'falls through', meaning, effectively 'switch' means 'jump to the right case statement, and just start running'. In this example, there are 4 case statements and none of them match; after all, you're asking the switch statement to find the case statement that goes with '5', and there isn't one.
Ordinarily that means the entire switch statement does nothing, but, there is a default: label in this switch block, which becomes the target case statement for everything that doesn't have an explicit case, thus, this switch statement jumps to default:.
Given that the basic switch falls through, it just 'falls through' to the case 1 block and just keeps falling through. However, that break; statement at the end of the 'case 3' set of statements exits the switch block and thus 4 is never printed.
This is not something you should ever be doing.
Fall-through is unexpected. Various linter tools straight up mark off fall-through as invalid code and will stop you from publishing/pushing to save you from yourself. All case (and default) blocks should end in a break;, and if you really need the fall through, add a comment // intentional fall-through to ensure other readers realize you wanted this feature.
The more modern flavours of switch no longer fall through. Which even more highlights the need not to rely on it.
the first case that will be matched is default, then all the code up to the break; will be executed. Try to move the default case to the end, add break to each of the cases and see how the behaviour change. Anyway, you should have break present in all your cases unless you want for one value match execute code in multiple consequent cases
Try to think about the process of it.
It checks the value passed to the switch() statement which is 5, but there is no case 5, so it goes to the default case.
But there is no code in the default case, so the logic goes to the next case which is case 1, it runs the code and print it.
Since there is no break statement, the logic goes to the next case which is case 2, it runs the code and print it.
Since there is no break statement, the logic goes to the next case which is case 3, it runs the code and print it.
The logic reaches the break statement in case 3, which stops the execution of the switch statement.

Can I use switch case in Java instead of IF, if I need several cases to be evaluated

I have a primitive question but I can't actually recall the answer.
What if I use Switch Cases instead of IF\ELSE IF. Will all cases get evaluated or break will break out of the whole switch cases and return the first satisfied condition only.
In other words, what if I want to check if someone has a car, bike and plane. And in my particular case someone has all of them would switch return all three as true or it will return the first case only and ignore the rest because of the break?
Sorry for inconvenience.
Thank you
From the Official Java Tutorials :
Each break statement terminates the enclosing switch statement.
In your particular case, if someone has a car, bike or a plane, you should construct more complex if\else statement.
But if you still prefer to use switch, you can do the following:
switch (possession)
{
case CAR:
case BIKE:
case PLANE:
doSomething();
break;
}
It will break out at the first matching. the best thing to do in your case is using logical operators in if statements.
if (hasCar && hasBike && hasPlane)
{
...
}
The break terminates the switch-statement.
Besides, switch evaluates a single variable, your case sounds a bit more complex to me.
certainly break will break the switch-case flow after encountering first break statementif no break is found then it will start the execution of all statement starting from first matching case,you can implement the logic inside case.and one thing more switch case is little bit faster than if-else
please see Why switch is faster than if
With switch the first case it finds a match runs and then all the following cases regardless of matching or not, provided you don't use break. By using break,only the actual match case runs and it is almost always only one. Therefore I do not regard in your problem using switch as a good approach, since you can handle it better with if-else.
Perhaps you would need to rewrite a new style of Data Structure to confirm this. The easyest way that I think is with a Boolean Array (bool[]);
Continuing with your example if you has the
Owner Class
, with
bool bike, bool car, bool motocycle... properties, witch you can write a
public bool[] ownArray()
function, that can be evaluated.
I hope this helps.
myEnum = 3;
...
switch (myEnum) {
case 1: System.out.println("This will not print"); break;
case 2: System.out.println("This will not print"); break;
case 3: System.out.println("This will print!"); //no break!
case 4: System.out.println("So will this, because there wasn't a break"); break;
case 5: System.out.println("But this won't, there was a break");
}
Switch-case in java could evaluate one case at a time. The moment it gets into one of the case, it would keep on executing the next statements (no matter, if those statement were part of other case ); until it hit a break;
In nutshell, A switch statement gives you the option to test for a range of values for your variables. They can be used instead of long, complex if … else if statements. The structure of the switch statement is this:
switch ( variable_to_test ) {
case value1: code_here1;
break;
case value2: code_here2;
case value3: code_here3;
break;
default:
values_not_caught_above;
}
In the above example if value2 is satifies, it will execute code_here2 and code_here3 as well (because there is no break statement)
Sadly, you can't test for a range of values after case, just the one value. So you can't do this:
case (user <= 18):

Switch case logical expression statement in Java - versus JS or PHP

in JavaScript and also I've seen it in PHP : You can use a logical expression inside you cases :
For Example :
switch(true){
case (d<10):
document.write("Less than 10");
break;
case (d==10):
document.write("Equal to 10");
break;
case (d>10):
document.write("Greater than 10");
break;
default:
document.write("Some dumb error. Probably not a number.");
}
I was wondering if we can do this in Java ... say I needed a to compare a very large range.
case 1 :
case 2 :
...
case 5000:
case 5001:
default:
It would be tedious to do. I could wrap my cases inside if statements but i was wondering it could be done like in JavaScript or PHP.
It is nice to have, but you cannot. Quoting JLS:
The body of a switch statement is known as a switch block.
Any statement immediately contained by the switch block may be labeled with one or more switch labels, which are case or default labels.
These labels are said to be associated with the switch statement, as are the values of the constant expressions (§15.28) or enum constants (§8.9.1) in the case labels.
These labels have to be constant expressions or enum constants.
No You cannot do that using switch in java. You have to use if-else to accomplish this.
See this link for more details.

Appropriate use of Multi-level Break in Java

I was recently coding a small java program (as design for an 8086 Assembler program) and I wound up in an interesting position -- I needed to exit out of a while loop from an inner switch-statement, something like this (pseudocode, obviously):
:MyLoop
While(foo)
switch (bar)
case '1': print '1'; break
case '0': print '0'; break
case ';': end while loop;
It seemed like the perfect place for a goto statement because a single "break" would only exit the switch statement,(especially considering that I was designing for assembly) but Java has no gotos!
I found instead that Java has something called a multi-level break, so by using "break MyLoop", the program would break out of both the switch case and the while loop. '
My question then -- is this an appropriate use of a multi-level break? If, for some reason, I wanted to keep the switch (instead of, say, nested else ifs) statement, is there an alternative way to mimic a multi-level break via "break" or "continue" alone?
Personally I would usually regard this as a hint to refactor the loop into its own method - then you can return from the whole method instead of just breaking out of the loop.
I personally find that clearer in most cases - but otherwise, this is exactly the kind of thing that labeled breaks are there for. It's generally cleaner (IMO) than having a separate boolean variable indicating whether or not to continue the loop.
is this an appropriate use of a multi-level break?
Yes.
is there an alternative way to mimic a multi-level break via "break" or "continue" alone?
You could set a boolean flag and then break at each level.
Jon Skeet's answer in code:
public void doSomething() {
while(foo) {
switch (bar) {
case '1': print '1'; break;
case '0': print '0'; break;
case ';': return; //Effectively exits the loop
}
}
}

Is there a programming language with better approach for switch's break statements?

It's the same syntax in a way too many languages:
switch (someValue) {
case OPTION_ONE:
case OPTION_LIKE_ONE:
case OPTION_ONE_SIMILAR:
doSomeStuff1();
break; // EXIT the switch
case OPTION_TWO_WITH_PRE_ACTION:
doPreActionStuff2();
// the default is to CONTINUE to next case
case OPTION_TWO:
doSomeStuff2();
break; // EXIT the switch
case OPTION_THREE:
doSomeStuff3();
break; // EXIT the switch
}
Now, all you know that break statements are required, because the switch will continue to the next case when break statement is missing. We have an example of that with OPTION_LIKE_ONE, OPTION_ONE_SIMILAR and OPTION_TWO_WITH_PRE_ACTION. The problem is that we only need this "skip to next case" very very very rarely. And very often we put break at the end of case.
It's very easy for a beginner to forget about it. And one of my C teachers even explained it to us as if it was a bug in C language (don't want to talk about it :)
I would like to ask if there are any other languages that I don't know of (or forgot about) that handle switch/case like this:
switch (someValue) {
case OPTION_ONE: continue; // CONTINUE to next case
case OPTION_LIKE_ONE: continue; // CONTINUE to next case
case OPTION_ONE_SIMILAR:
doSomeStuff1();
// the default is to EXIT the switch
case OPTION_TWO_WITH_PRE_ACTION:
doPreActionStuff2();
continue; // CONTINUE to next case
case OPTION_TWO:
doSomeStuff2();
// the default is to EXIT the switch
case OPTION_THREE:
doSomeStuff3();
// the default is to EXIT the switch
}
The second question: is there any historical meaning to why we have the current break approach in C? Maybe continue to next case was used far more often than we use it these days ?
From this article, I can enumerate some languages that don't require a break-like statement:
Ada (no fallthrough)
Eiffel (no fallthrough)
Pascal (no fallthrough)
Go - fallthrough
Perl - continue
Ruby (no fallthrough)
VB, VBA, VBS, VB.NET (no fallthrough)
To be continued by someone else...
Your second question is pretty interesting. Assuming only C, I believe this decision keeps the language cohesive. Since break is a jump, it must be explicitly written.
Scala pattern matching I think is a huge improvement in these cases. :)
object MatchTest2 extends Application {
def matchTest(x: Any): Any = x match {
case 1 => "one"
case "two" => 2
case y: Int => "scala.Int"
}
println(matchTest("two"))
}
Sample from scala-lang.org
And VB .NET handles it a little more like how you expect it should work.
Select Case i
Case 1 to 3
DoStuff(i)
Case 4,5,6
DoStuffDifferently(i)
Case Is >= 7
DoStuffDifferentlyRedux(i)
Case Else
DoStuffNegativeNumberOrZero(i)
End Select
There is no fall through at all, without possibly using a Goto
Here is the answer:
http://en.wikipedia.org/wiki/Switch_statement
It's called fall-through statement (continue in the example) and it exists in the following languages:
Go, Perl, C#
In C# it won't compile without break or goto case statement (except when there's no pre-action).
PASCAL doesn't have fall-through
I think the answer to your question of why it is this way centers around two behaviors, both having to do with the generated assembly code from the C source.
The first is that in assembly, the current instruction is executed, and unless there is a jump or some other flow control instruction, the instruction at the next address will be executed. Performing a naive compile of the switch statement to assembly would generate code that would just start executing the first instruction, which would be to see if there was a matching condition...
The second related reason is the notion of a branch table or jump list. Basically the compiler can take what it knows about your value, and create some extremely efficient machine code for the same thing. Take for example a simple function like atoi that converts a string representation of a number and returns it in integer form. Simplifying things way down to support just a single digit, you could write some code similar to this:
int atoi(char c) {
switch (c) {
case '0': return 0;
case '1': return 1;
// ....
}
}
The naive compiler would perhaps just convert that to a series of if/then blocks, meaning a substantial amount of CPU cycles would be taken for the number 9, while 0 returns almost immediately. Using a branch table the compiler could emit some [psuedo] assembly that would immediately "jump" to the correct return clause:
0x1000 # stick value of c in a register
0x1004 # jump to address c + calculated offset
# example '0' would be 0x30, the offset in for this sample
# would always be 0x0FD8... thus 0x30 + 0x0FD8 = 0x1008
0x1008 # return 0
Apology: my assembly and C skills are quite rusty. I hope this helps clarify things.
0x
Hey, don't forget COBOL's EVALUATE:
EVALUATE MENU-INPUT
WHEN "0" PERFORM INIT-PROC
WHEN "1" THRU "9" PERFORM PROCESS-PROC
WHEN "R" PERFORM READ-PARMS
WHEN "X" PERFORM CLEANUP-PROC
WHEN OTHER PERFORM ERROR-PROC
END-EVALUATE.
Ada doesn't have fallthrough, and requires that all values are explicitly handled, or a "others" clause added to handle the rest.
SQL CASE statement also does not fallthrough.
XSLT has which does not fallthrough.
It seems to be C and derived languages that have the fallthrough. It's quite insidious, and the only real use I've seen is implementing duff's device.
http://www.adaic.org/whyada/intro4.html
Python doesn't have one at all.
Took some getting used to but I have some horrendous memories hunting through massive switch blocks back in my C# days. I'm much happier without it.
Although not exactly what you asked for, Groovy has a very powerful switch statement
The OP talks about "fall through", but very seldom have I ever been bit by that.
Many many times, however I have been bit by designs that are non-extensible. To wit, "switch (kbHit)" statements, with a few hundred keys in there, that are a maintenance nightmare, and a frequent location for "god methods", and giant piles of spaghetti-code.
Using switch is often a sign of poor object oriented programming. As another person answered, "2 uses of Switch in 48 source files", in one of his application, shows a programmer who does not rely heavily on this construct. From his metric, I surmise that he is probably at least a good structured programmer, and probably understands OOP/OOD as well.
OOP (not necessarily only C++) programmers, and even pure C users who do not have an object description technique forced upon them, could implement an "inversion of control" container that publishes a "key was hit" and allows subscribers to plug in their handlers for "on keyboard code x". This can make reading your code much easier.
Pure speculation, but:
I occasionally write C or Java in which I say something like:
switch (tranCode)
{
case 'A':
case 'D':
case 'R':
processCredit();
break;
case 'B':
case 'G':
processDebit();
break;
default:
processSpecial();
}
That is, I deliberately use fall-thru to let several values fire the same operation.
I wonder if this is what the inventors of C were thinking of when they created the SWITCH statement, that this would be the normal usage.
Tcl doesn't automatically fall through.
In object oriented languages you use the Chain of Responsibility pattern. How that is implemented can vary. What you are describing in your example, is mixing a state machine with behavior by abusing a switch statement. For your particular example a Chain of Responsibility pattern with the parameter that the chain evaluates being a State pattern, that mutates as it goes down the chain, would be the appropriate implementation.
languages are too much and I can't answer for sure that there's not such a language, provided it is a "derivative" of C in syntax, because other languages using different syntax and where the case does not "continue" naturally exist, e.g. Fortran. I don't know languages that uses an explicit "continue" to continue to the following case.
I believe it is historical reason due to the way such a case could be programmed at a "low level". Moreover the syntactical aspect of the case is that of a label, and break works like in loops, so you can imagine an equivalent like this:
if ( case == 1 ) goto lab1;
if ( case == 2 ) goto lab2;
if ( case == 3 ) goto lab3;
//...
default:
// default
goto switch_end;
lab1:
// do things
goto switch_end; // if break is present
lab2:
// do things, and follow to lab3
lab3:
// lab3 stuffs
goto switch_end;
//
...
switch_end: // past all labS.
More languages without a fallthough:
XSLT
JSTL
Algol
PL/1
Lima does it like this:
if someValue == ?1 ::
OPTION_ONE: fall
OPTION_LIKE_ONE: fall
OPTION_ONE_SIMILAR:
doSomeStuff1[]
;; the default is to EXIT the switch
OPTION_TWO_WITH_PRE_ACTION:
doPreActionStuff2[]
fall ;; fall through to the next case
OPTION_TWO:
doSomeStuff2[]
OPTION_THREE:
doSomeStuff3[]

Categories