Why doesn't the compiler automatically put break statements after each code block in the switch? Is it for historical reasons? When would you want multiple code blocks to execute?
Sometimes it is helpful to have multiple cases associated with the same code block, such as
case 'A':
case 'B':
case 'C':
doSomething();
break;
case 'D':
case 'E':
doSomethingElse();
break;
etc. Just an example.
In my experience, usually it is bad style to "fall through" and have multiple blocks of code execute for one case, but there may be uses for it in some situations.
Historically, it's because the case was essentially defining a label, also known as the target point of a goto call. The switch statement and its associated cases really just represent a multiway branch with multiple potential entry points into a stream of code.
All that said, it has been noted a nearly infinite number of times that break is almost always the default behavior that you'd rather have at the end of every case.
Java comes from C and that is the syntax from C.
There are times where you want multiple case statements to just have one execution path.
Below is a sample that will tell you how many days in a month.
class SwitchDemo2 {
public static void main(String[] args) {
int month = 2;
int year = 2000;
int numDays = 0;
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
numDays = 31;
break;
case 4:
case 6:
case 9:
case 11:
numDays = 30;
break;
case 2:
if ( ((year % 4 == 0) && !(year % 100 == 0))
|| (year % 400 == 0) )
numDays = 29;
else
numDays = 28;
break;
default:
System.out.println("Invalid month.");
break;
}
System.out.println("Number of Days = " + numDays);
}
}
I think it is a mistake. As a language construct it is just as easy to have break as the default and instead have a fallthrough keyword. Most of the code I have written and read has a break after every case.
You can do all sorts of interesting things with case fall-through.
For example, lets say you want to do a particular action for all cases, but in a certain case you want to do that action plus something else. Using a switch statement with fall-through would make it quite easy.
switch (someValue)
{
case extendedActionValue:
// do extended action here, falls through to normal action
case normalActionValue:
case otherNormalActionValue:
// do normal action here
break;
}
Of course, it is easy to forget the break statement at the end of a case and cause unexpected behavior. Good compilers will warn you when you omit the break statement.
Why doesn't the compiler automatically put break statements after each code block in the switch?
Leaving aside the good desire to be able to use the identical block for several cases (which could be special-cased)...
Is it for historical reasons? When would you want multiple code blocks to execute?
It's mainly for compatibility with C, and is arguably an ancient hack from the days of old when goto keywords roamed the earth. It does enable some amazing things, of course, such as Duff's Device, but whether that's a point in its favor or against is… argumentative at best.
The break after switch cases is used to avoid the fallthrough in the switch statements. Though interestingly this now can be achieved through the newly formed switch labels as implemented via JEP-325.
With these changes, the break with every switch case can be avoided as demonstrated further :-
public class SwitchExpressionsNoFallThrough {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int value = scanner.nextInt();
/*
* Before JEP-325
*/
switch (value) {
case 1:
System.out.println("one");
case 2:
System.out.println("two");
default:
System.out.println("many");
}
/*
* After JEP-325
*/
switch (value) {
case 1 ->System.out.println("one");
case 2 ->System.out.println("two");
default ->System.out.println("many");
}
}
}
On executing the above code with JDK-12, the comparative output could be seen as
//input
1
// output from the implementation before JEP-325
one
two
many
// output from the implementation after JEP-325
one
and
//input
2
// output from the implementation before JEP-325
two
many
// output from the implementation after JEP-325
two
and of course the thing unchanged
// input
3
many // default case match
many // branches to 'default' as well
So you do not have to repeat code if you need several cases to do the same thing:
case THIS:
case THAT:
{
code;
break;
}
Or you can do things like :
case THIS:
{
do this;
}
case THAT:
{
do that;
}
In a cascade fashion.
Really bug/confusion prone, if you ask me.
As far as the historical record goes, Tony Hoare invented the case statement in the 1960s, during the "structured programming" revolution. Tony's case statement supported multiple labels per case and automatic exit with no stinking break statements. The requirement for an explicit break was something that came out of the BCPL/B/C line. Dennis Ritchie writes (in ACM HOPL-II):
For example, the endcase that escapes from a BCPL switchon statement was not present in the language
when we learned it in the 1960s, and so the overloading of the break keyword to escape
from the B and C switch statement owes to divergent evolution rather than conscious change.
I haven't been able to find any historical writings about BCPL, but Ritchie's comment suggests that the break was more or less a historical accident. BCPL later fixed the problem, but perhaps Ritchie and Thompson were too busy inventing Unix to be bothered with such a detail :-)
Java is derived from C, whose heritage includes a technique known as Duff's Device .
It's an optimization that relies on the fact that control falls through from one case to the next, in the absence of a break; statement. By the time C was standardized, there was plenty of code like that "in the wild", and it would have been counterproductive to change the language to break such constructions.
As people said before, it is to allow fall-through and it is not a mistake, it is a feature.
If too many break statements annoy you, you can easily get rid of them by using return statements instead. This is actually a good practice, because your methods should be as small as possible (for the sake of readability and maintainability), so a switch statement is already big enough for a method, hence, a good method should not contain anything else, this is an example:
public class SwitchTester{
private static final Log log = LogFactory.getLog(SwitchTester.class);
public static void main(String[] args){
log.info(monthsOfTheSeason(Season.WINTER));
log.info(monthsOfTheSeason(Season.SPRING));
log.info(monthsOfTheSeason(Season.SUMMER));
log.info(monthsOfTheSeason(Season.AUTUMN));
}
enum Season{WINTER, SPRING, SUMMER, AUTUMN};
static String monthsOfTheSeason(Season season){
switch(season){
case WINTER:
return "Dec, Jan, Feb";
case SPRING:
return "Mar, Apr, May";
case SUMMER:
return "Jun, Jul, Aug";
case AUTUMN:
return "Sep, Oct, Nov";
default:
//actually a NullPointerException will be thrown before reaching this
throw new IllegalArgumentException("Season must not be null");
}
}
}
The execution prints:
12:37:25.760 [main] INFO lang.SwitchTester - Dec, Jan, Feb
12:37:25.762 [main] INFO lang.SwitchTester - Mar, Apr, May
12:37:25.762 [main] INFO lang.SwitchTester - Jun, Jul, Aug
12:37:25.762 [main] INFO lang.SwitchTester - Sep, Oct, Nov
as expected.
It is an old question but actually I ran into using the case without break statement today. Not using break is actually very useful when you need to combine different functions in sequence.
e.g. using http response codes to authenticate user with time token
server response code 401 - token is outdated -> regenerate token and log user in.
server response code 200 - token is OK -> log user in.
in case statements:
case 404:
case 500:
{
Log.v("Server responses","Unable to respond due to server error");
break;
}
case 401:
{
//regenerate token
}
case 200:
{
// log in user
break;
}
Using this you do not need to call log in user function for 401 response because when the token is regenerated, the runtime jumps into the case 200.
Not having an automatic break added by the compiler makes it possible to use a switch/case to test for conditions like 1 <= a <= 3 by removing the break statement from 1 and 2.
switch(a) {
case 1: //I'm between 1 and 3
case 2: //I'm between 1 and 3
case 3: //I'm between 1 and 3
break;
}
because there are situations where you want to flow through the first block for example to avoid writing the same code in multiple blocks but still be able to divide them for mroe control. There are also a ton of other reasons.
You can makes easily to separate other type of number, month, count.
This is better then if in this case;
public static void spanishNumbers(String span){
span = span.toLowerCase().replace(" ", "");
switch (span){
case "1":
case "jan": System.out.println("uno"); break;
case "2":
case "feb": System.out.println("dos"); break;
case "3":
case "mar": System.out.println("tres"); break;
case "4":
case "apr": System.out.println("cuatro"); break;
case "5":
case "may": System.out.println("cinco"); break;
case "6":
case "jun": System.out.println("seis"); break;
case "7":
case "jul": System.out.println("seite"); break;
case "8":
case "aug": System.out.println("ocho"); break;
case "9":
case "sep": System.out.println("nueve"); break;
case "10":
case "oct": System.out.println("diez"); break;
}
}
I am now working on project where I am in need of break in my switch statement otherwise the code won't work. Bear with me and I will give you a good example of why you need break in your switch statement.
Imagine you have three states, one that waits for the user to enter a number, the second to calculate it and the third to print the sum.
In that case you have:
State1 - Wait for user to enter a number
State2 - Print the sum
state3 - Calculate the sum
Looking at the states, you would want the order of exaction to start on state1, then state3 and finally state2. Otherwise we will only print users input without calculating the sum. Just to clarify it again, we wait for the user to enter a value, then calculate the sum and prints the sum.
Here is an example code:
while(1){
switch(state){
case state1:
// Wait for user input code
state = state3; // Jump to state3
break;
case state2:
//Print the sum code
state = state3; // Jump to state3;
case state3:
// Calculate the sum code
state = wait; // Jump to state1
break;
}
}
If we don't use break, it will execute in this order, state1, state2 and state3. But using break, we avoid this scenario, and can order in the right procedure which is to begin with state1, then state3 and last but not least state2.
Exactly, because with some clever placement you can execute blocks in cascade.
Related
int month = input.nextInt();
switch (month) {
case 1:
System.out.println(“January”);
case 2:
System.out.println(“February”); break;
case 3:
System.out.println(“March”); break;
case 4:
System.out.println(“April”);
case 5:
System.out.println(“May”); break;
default:
System.out.println(“Invalid”); break;
}
How do I convert it from switch statement into if-else statment?
the breaks are intentional, this is a college assignment.
In pseudo code, you could check all connected parts, without a break statement, together in a single statement and check the values in another nested if statement.
if 1 or 2
if 1 print january
print february
else if 3 print march
else if 4 or 5
if 4 print april
print may
else print invalid
int month = input.nextInt();
if(month==1){
System.out.println(“January”);
System.out.println(“February”);
}else if(month==2){
System.out.println(“February”);
}
you should be able to repeat that for the next cases. Please try to clean up your code next time, if we are giving time to answer you should at least put in time to ask properly, thanks
I am trying a switch statement to dynamically determine which part of an actionbar dropdown spinner is being selected. This switch statement does not even go to my default case, what am I doing wrong?
public boolean onNavigationItemSelected(int itemPosition, long itemId) {
// TODO Auto-generated method stub
//restart fragment with selected spinner item's api call
TypedArray mArray = getResources().obtainTypedArray(R.array.spinner_actionbar);
switch(mArray.getResourceId(itemPosition, 0)){
case R.string.spinner_timeline:
break;
case R.string.spinner_profile:
break;
case R.string.spinner_top_posts:
break;
case 0:
break;
default:
break;
}
mArray.recycle();
return false;
}
mArray.getResourceId(itemPosition, 0) returns the position of an arraylist OR 0, and none of my cases not even case 0 is being called
Thanks for any insight, this is using the android framework
You have empty cases in your switch-case block. You want to do something inside each case, besides just break out of the block. For example:
case R.string.spinner_timeline:
System.out.println(R.string.spinner_timeline);
break;
case R.string.spinner_profile:
System.out.println(R.string.spinner_profile);
break;
case R.string.spinner_top_posts:
System.out.println(R.string.spinner_top_posts);
break;
case 0:
break;
default:
System.out.println("default case...");
break;
two cases might be triggered by your code:
case 0 and default
both of those are break so yo cannot tell which is triggered.
R.ids are not position ids most likely
Here, the switch statement is used without making use of why and when to use the switch statement.
A switch statement is useful when you need to select one of several alternatives based on the value of an integer, a character, or a String variable. The basic form of the switch statement is this:
switch (expression)
{
case constant:
statements;
break;
[ case constant-2:
statements;
break; ] ...
[ default:
statements;
break; ] ...
}
In your case, you are using the switch and not telling what to do when you enter the switch-case. As soon as you enter, you leave from the case using the break statement. You are doing the same thing in default case also.
Reference links that you should go through:
Java Switch-case
http://www.dummies.com/how-to/content/switch-statements-in-java.html
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
I found one interesting way to use a switch statement in Java, and I can't catch all logic.
Can someone help to understand all details in depth?
Here is code:
private static int counter = 0;
public static Shape randomFactory() {
int xVal = rand.nextInt(100);
int yVal = rand.nextInt(100);
int dim = rand.nextInt(100);
switch (counter++ % 3) {
default:
case 0:
return new Circle(xVal, yVal, dim);
case 1:
return new Square(xVal, yVal, dim);
case 2:
return new Line(xVal, yVal, dim);
}
}
In general I understand this logic,
What exactly default mean here:
switch (counter++ % 3) {
default:
And how does switch (counter++ % 3) find equals case? And here isn't any brake presented.
Any suggestions?
default marks the block that would get executed if the switch expression does not match any case labels. In your example, default contains no break, so it would fall through and execute the same code as for case 0.
Note that, since you have a case label for every possible value of the switch expression, the default is effectively a no-op.
In your case you are using default block at the very beginning of case statement, which is a bit strange since default means that this part of code will execute if none of the case conditions have matched. You should also check about fall through. You avoided it with returns, but it is usually done with break.
switch (counter++ % 3) calculates first counter++ % 3 and then matches it with appropriate case.
The default clause is useless here: due to your %3 it should never happen.
Would you modify the %3 to %4 it would catch some data, but as there is neither a break nor a return statement it would execute just like case 0.
default:
It simply means of none of the conditions in switch statement are matched code corresponding to default will be executed.
default will execute when there is no matching in case.In this case default is useless since it will never execute. Consider the following case.
switch(input){
case 1:
// do something
break;
case 2:
// do something
break;
default:
// if input is not 1 or 2 this will execute.
break;
}
Default is one of the switch labels which contains statements to execute if none of the other labels match. From JLS §14.11:
At most one default label may be associated with the same switch statement.
If no case matches but there is a default label, then all statements after the matching default 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 default label, then the entire switch statement completes normally.
If no case matches and there is no default label, then no further action is taken and the switch statement completes normally.
So in this case default label will do nothing as there always will be a match.
There is no break inside default so it do nothing, it is just example of fallthrough.
Please read about switch statements from here -
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
default means if any case doesn't match with switch condition then default is called.
counter++ % 3 ..your counter was 0 so it will match with case 0.
Im writing a program in java and part of it has to evaluate cleavages in a protein sequence.
I have to evaluate if the cleavage happens at certain groups on either end which results in if, else/elseif statements with either annoying logicals in several places, nesting, or just several "if"s and/or "else"s. I've used switch as an alternative to having to evaluate several "if"s and logicals (&&, ||) each time a cleavage happens (this loop will iterate literally MILLIONS of times, possible tens or hundreds of millions).
heres the chunk of code:
-.getSeq() gets a string representing the sequence of a protein
-startPos and endPos are the indices of the cleavages on either end
-sorry if the if statement lines are broken into multiple lines or convoluted, but that's kind of my case and point about the logicals.
/**0: non-tryptic, 1: half-tryptic, 2: fully tryptic**************/
public boolean checkPep(int trypticity){
boolean evaluator = false;
int prev = 0;
if (startPos != 0){
prev = 1;
}
switch(trypticity){
/**do not check cleavage if peptide can be non-tryptic*/
case 0:
evaluator = true;
break;
/***half-tryptic*/
/**check if either the start OR end cleavage is tryptic*/
case 1:
switch(protein.getSeq().charAt(startPos-prev)){
case 'K':
evaluator = true;
break;
case 'R':
evaluator = true;
break;
default :
switch(protein.getSeq().charAt(endPos)){
case 'K':
evaluator = true;
break;
case 'R':
evaluator = true;
break;
default:
evaluator = false;
break;
}
break;
}
break;
/**fully tryptic*/
/**if first cleavage is tryptic, check end cleavage*/
/**evaluator = true IFF both cleavages are tryptic*******/
case 2:
if(((protein.getSeq().charAt(startPos-1)) == 'K') || ((protein.getSeq().charAt(startPos-1)) == 'R')){
if(((protein.getSeq().charAt(endPos)) == 'K') || ((protein.getSeq().charAt(endPos)) == 'R')){
evaluator = true;
}else{
evaluator = false;
}
}else{
evaluator = false;
}
break;
}
return evaluator;
}
This kind of thing is what we'd call a micro-optimization.
Using a switch instead of an if chain may be beneficial ... or it may not. It very much depends on the context.
The only way to be sure is to carefully benchmark the code, comparing the versions with and without the potential optimization. It is also a good idea to profile first so that you don't waste time optimizing code that doesn't really matter.
Note that the effects of a given micro-optimization may vary depending on your actual execution hardware, Operating System and JVM version / flavour. (And possibly other things too ... like how much physical memory is available and how big the heap is.) Predicting the benefits from first principles is hard, and it is always possible that a platform change can negate all of your hand tuning work.
I have a yes or no question & answer. I would like to ask another yes or no question if yes was the answer. My instructor wants us to use charAt(0) as input for the answer.
Is it possible to have a switch statement within another one (like a nested if statement)?
EDIT: Here is a sample of my pseudo code =
display "Would you like to add a link (y = yes or n = no)? "
input addLink
switch (link)
case 'y':
display "Would you like to pay 3 months in advance " + "(y = yes or n = no)?"
input advancePay
switch(advPay)
case 'y':
linkCost = 0.10 * (3 * 14.95)
case 'n'
linkCost = 14.95
case 'n'
linkCost = 0.00
Yes, but don't. If you need a further level of logic like that, place the second Switch in its own method with a descriptive name.
EDIT: By the example you've added, you've got two Boolean conditions. I would recommend against using switch at all, using if & else conditionals instead. Use (STRING.charAt(0) == 'y') as your test case, or something methodical like boolean isY(final String STRING) { return (STRING.charAt(0) == 'y' || STRING.charAt(0) == 'Y'); }
Yes. Switches break the language block statement pattern, but this is mainly because of C/C++ from which the switch statement used by Java is based.
In all three languages, the switch statement takes the following form:
switch(variable) {
case n:
statement 1;
statement n;
(optional) break;
case n+1:
statement 1;
statement n;
(optional) break;
// Optionally more statements
(optional) default:
statement 1;
statement n;
}
Because a switch statement breaks the traditional language pattern, many programmers wrap their multiple statements in a case using the traditional block style: { }
This is because most constructs in all three languages allow block style statements to be considered as one statement, but the switch statement does not require block style to execute multiple statements in a single case.
Without the break statement separating each case, there will be "fall through" - if case n was matched and did not have a break, the code under it (case n + 1) would be executed - if case n + 1 did not have a break and was matched, the default code would execute, if neither had a break, when matching case n, the code for case n, case n+1 and default would be executed.
The default is optional, and specifies a default action for a switch statement to execute. Typically, the default condition is either a generic handler, or a good place to throw an exception if the value could not logically be any other than the values in the switch statement.
To illustrate a switch statement executing inside a switch statement, take a look at this contrived example:
String message = null;
int outerVariable = getOuterVariable();
switch(outerVariable) {
case n:
statement 1;
statement n;
break;
case n+1:
int innerVariable = getInnerVariable();
switch(innerVariable) {
case 1:
message = "IT WAS 1";
break;
default:
message = "WHY WOULD YOU DO THIS? OH THE HUMANITY!";
}
break;
// Optionally more statements
(optional) default:
statement 1;
statement n;
}
It is possible, but that would be very convoluted and hard to read. There's almost certainly a better way, such as calling a method within the first switch statement and doing any more necessary processing (including another switch if necessary) in that method.
Most programming languages are orthogonal. That means, using a feature usually does not depend on the location, if meaningful.
For example, you cannot declare a local variable as public.