So as a beginner I was trying to use the switch as follows:
switch (c_a.getText())
{
case "Customer":
{
new LoginPage().setVisible(true);
}
case "Admin":
{
new LoginPageadmin().setVisible(true);
}
default:
{
JOptionPane.showMessageDialog(this, "Please try again");
}
}
Although the problem here is that it opens up the JOptionPane in default as well. What am I doing wrong?
Within a switch statement, you need to place break statements, or else additional switch blocks can be executed. Here is what it says in a Java tutorial concerning switch statements:
Each break statement terminates the enclosing switch statement. 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.
Without a break;, your code will often "fall through" the switch blocks, as is the case here.
you're missing the break statement
switch (c_a.getText()) {
case "Customer": {
new LoginPage().setVisible(true);
break;
}
case "Admin": {
new LoginPageadmin().setVisible(true);
break;
}
default: {
JOptionPane.showMessageDialog(this, "Please try again");
break;
}
}
source: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
Related
I have this code with the switch statement which I got from this post, and it works absolutely fine:
String getOrdinal(final int day) {
if (day >= 11 && day <= 13) {
return "th";
}
switch (day % 10) {
case 1: return "st";
case 2: return "nd";
case 3: return "rd";
default: return "th";
}
}
But if I change it to something like the following, it breaks, as all the cases besides case 1 gets executed:
static String getOrdinal(final int day) {
StringBuilder ordinalBuilder = new StringBuilder();
ordinalBuilder.append("<sup>");
if (day >= 11 && day <= 13) {
ordinalBuilder.append("th") ;
}
switch (day % 10) {
case 1: ordinalBuilder.append("st");
case 2: ordinalBuilder.append("nd");
case 3: ordinalBuilder.append("rd");
default: ordinalBuilder.append("th");
}
ordinalBuilder.append("</sup>");
return ordinalBuilder.toString();
}
This prints 2<sup>ndrdth</sup> when I pass in 2. I tried changing the builder to buffer but I got the same response... Could this be a bug or am I making some mistake?
It's a bug in your code. You forgot to put in a break after each case:
switch (day % 10) {
case 1: ordinalBuilder.append("st"); break;
case 2: ordinalBuilder.append("nd"); break;
case 3: ordinalBuilder.append("rd"); break;
default: ordinalBuilder.append("th"); break;
}
I don't see any bug here, at least not in the way the language is working. The behavior of a switch statement, by design, is that it will start executing statements at the case label which matches the argument, and then continue until the end of the block. So
switch (x) {
case 1:
// do thing 1
case 2:
// do thing 2
case 3:
// do thing 3
default:
// do nothing
}
will do both things 2 and 3 if x is 2, and will do things 1, 2, and 3 if x is 1.
To get the behavior you're probably looking for, end each case with a break:
switch (x) {
case 1:
// do thing 1
break;
case 2:
// do thing 2
break;
case 3:
// do thing 3
break;
default:
// do nothing
break;
}
(strictly speaking the break at the very end is unnecessary, but I often put it in out of habit).
The reason you didn't have this problem in the first code example is that return is like a super-break: it has the same effect as break, namely ending execution within the switch block, but it also ends execution of the whole method.
you need to add a 'break' statement in every switch case.
It was worked previously because you made a return from method...
A "break;" statement separates the cases from one another so in order to execute the statements in a specific case just break the case as soon as it comes to an end.
If you don't use break the compiler thinks that it can continue execution of all the cases up to the end of the program.
The first version returns before continuing on in the case statement. The second version needs a break; statement to get the same behavior.
Luckily with the introduction of switch statements on Java 12 which also introduced
"arrow case" labels that eliminate the need for break statements to
prevent fall through (source).
Therefore the modern version of your code looks like the following:
String getOrdinal(final int day) {
if (day >= 11 && day <= 13) {
return "th";
}
return switch (day % 10) {
case 1 -> "st";
case 2 -> "nd";
case 3 -> "rd";
default -> "th";
};
}
I see this question is over 8 years old, but this answer should help anyone landing on this page.
Firstly lets's understand how switch cases work. In C, C++, Java, JavaScript, and PHP while executing switch statements all the cases following the satisfactory case are executed, unlike in Go where only selected case is executed.
For example:
public class Main
{
public static void main(String[] args) {
int day = 11;
switch (day % 10) {
case 1: System.out.println("st");
case 2: System.out.println("nd");
case 3: System.out.println("rd");
default: System.out.println("th");
}
}
}
Currently, day value is set to 11 and hence very first case satisfy the condition, and hence all below cases would be executed. The output should look like the one below:
st
nd
rd
th
Now let's change day value to 13 resulting in the third case to satisfy the condition and hence below output is obtained:
rd
th
Hence if you want to break the code after first satisfactory case is found then put break; condition in the end. In the code mentioned in the question return; does the job of breaking the code.
Also, most of the novice java programmers believe that SWITCH statements are syntactical sugar to IF statements wherein programmers don't have to repetitively mention conditions. But that's not the case as IF's are meant to exit after the execution of satisfactory condition while SWITCH still continues execution.
Switch cases can be utilized to achieve the purpose like one mentioned in below example:
wherein
for Grade A "Excellent!" should be printed
for Grade B and C "Well done" should be printed
for Grade D "You passed \n Try hard next time" should be printed
for Grade F "Try hard next time" should be printed
and if not a valid case i.e grade is found than "Invalid Grade" should be printed.
public class Test {
public static void main(String args[]) {
// char grade = args[0].charAt(0);
char grade = 'C';
switch(grade) {
case 'A' :
System.out.println("Excellent!");
break;
case 'B' :
case 'C' :
System.out.println("Well done");
break;
case 'D' :
System.out.println("You passed");
case 'F' :
System.out.println("Try hard next time");
break;
default :
System.out.println("Invalid grade");
}
System.out.println("Your grade is " + grade);
}
}
Add a break statement at the end of the every line in each case or just use the return statement.
I'm new to Java and am learning switch statements. However, the wrong case (case "two") seems to be matched. I suspect that it's because of the lack of break; after case "one", but can someone please explain to me the logic behind Java switch statements? Why is case "two" matched at all when the values don't even match?
Here is my code:
String a = "one";
switch(a) {
case "one": System.out.println("a is one");
case "two": System.out.println("a is two");
default: System.out.println("numbers");
}
I expected output:
a is one
numbers
But got:
a is one
a is two
numbers
The case statement is evaluated from top to bottom, when it finds a match it will enter at that point and continue downwards until a break is found (or it gets to the bottom without finding a match). You cannot drop into "one", skip over "two" and re-enter a default.
Default is used when none of the other cases above it match
You need break statements
String a = "one";
switch(a) {
case "one": System.out.println("a is one"); break;
case "two": System.out.println("a is two"); break;
default: //
}
System.out.println("numbers")
Then maybe print the numbers afterward
Each break statement terminates the enclosing switch statement. 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.
If all the cases has been checked and not passed then default case will be executed. Thus in your case the code should be like this.
String a = "one";
switch(a) {
case "one":
System.out.println("a is one");
break;
case "two":
System.out.println("a is two");
break
default:
System.out.println("None of the cases matched ");
}
System.out.println("numbers");
In switch statement, the value of the expression is compared with each of the literal values in the case statements. If a match is found l, the code sequence following the case is executed. However, the default statement is optional.
The break statement is used inside the switch to terminate a statement sequence.
When a break statement is encountered, execution branches to the first of code that follows the entireswitch statement.
This has the effect of jumping out of the switch.
If you omit the break execution will continue on into the next case.
I've tried looking this up, and although other people have asked this, their situation applies to different things (as far as I can tell).
I am learning Java, and I am creating a program that "talks" with the user, asking questions and stuff. As a step to actually learning the concepts of object-oriented programming, I created a class that helps my main project NOT be filled with the handling of questions, instead I put the handling and returns for most questions in a class called ConversationHelper.
I created a method in my ConversationHelper for asking Yes/No questions. Here is its code:
public boolean askYNQuestion(String question) {
Scanner input = new Scanner(System.in);
boolean isInputCorrect = false;
while(isInputCorrect == false) {
displayQuestion(question + " (Y or N)");
String readin = input.nextLine();
switch (readin.toLowerCase()) {
case "n":
return false;
break;
case "y":
return true;
break;
case "yes":
return true;
break;
case "no":
return false;
break;
case "false":
return false;
break;
case "true":
return true;
break;
default:
break;
}
}
System.out.println("THIS IS NOT SUPPOSED TO HAPPEN! FALSE DEFAULT!");
return false;
}
The problem with this is more of an annoyance than anything else. Every break in the switch statement comes up with "unreachable code" because there is a return statement before it. However, this is meant to happen.
Netbeans now tells me, at build, that the "compiler ran with errors." Not only is this just annoying, but it makes it hard to tell if the error is this known error, or if it is another error that needs my attention, wasting time when I'm trying to make my program work.
I'm looking for either a better way to do this that won't generate errors, or a way to force disable this error from coming up. I am running Netbeans, with Java 8. Any help would be greatly appreciated.
Thanks!
A return will act as a break. There is no need to use both. If you receive the message that you have unreachable code, then there is either no point in it being there, or something you did previously is out of order logically.
As a second point, just to improve your code, you can combine conditions in your switch statement. If you have multiple items which will return the same thing, you can list them one after the other and put a single return for them all.
switch (readin.toLowerCase()) {
case "n":
case "no":
case "false":
return false;
case "y":
case "yes":
case "true":
return true;
default:
break;
}
I am trying to make a switch that will step through the code like in Javascript by adding "jedi++" at the end but it won't let me do that any suggestions on how I can accomplish that? Here is a snippet of the code.
switch(jedi){
case 1:
while(!input.equalsIgnoreCase("guardian") && !input.equalsIgnoreCase("sentinel") && !input.equalsIgnoreCase("consular")){
System.out.println("Please enter the path followed by this Jedi.");
System.out.println("(Guardian, Sentinel or Consular)");
}
registrant.setPath(input);
break;
case 2:
while(!input.equalsIgnoreCase("master") && !input.equalsIgnoreCase("knight") && !input.equalsIgnoreCase("padawan")
&& !input.equalsIgnoreCase("youngling")){
System.out.println("Please enter the Jedi's Rank.");
System.out.println("(Master, Knight, Padawan, Youngling)");
input = keyboard.nextLine();
}
registrant.setRank(input);
break;
jedi++;
}
Do you want to jedi++ in all the cases or just in case 2?
If it's just for case 2, you could do
case 2:
....
jedi++;
break;
case 3:
....
if it's for all the cases, you could do jedi++ after the switch block.
Statements can exist only within the case. since jedi++ is not part of case, its throwing error. Putting the increment statement under required case statement will solve the issue.
I was answering a Java test and come across the question:
Which of the following statements is true?
A. In an assert statement, the expression after the colon ( : ) can
be any Java expression.
B. If a switch block has no default, adding an assert default is considered appropriate.
C. In an assert statement, if the expression after the colon ( : ) does not have a
value, the assert's error message will be empty.
D. It is appropriate to handle assertion failures using a catch clause.
The right answer is B. To be honest, I answered that question by excluding another obviously wrong cases, but I can't get the point of that question actually. Could anyone explain why it is true? Where can it be helpful?
I guess it means you should protect yourself from missing a switch case.
Say you have an enum Color {red, green} and this switch in the code:
switch(color) {
case red:
doSomethingRed();
break;
case green:
doSomethingGreen();
break;
}
If in the future you add a new color blue, you can forget to add a case for it in the switch.
Adding failing assert to the default case will throw AssertionError and you will discover your mistake .
switch(color) {
case red:
doSomethingRed();
break;
case green:
doSomethingGreen();
break;
default:
assert false : "Oops! Unknown color"
}
This depends on the case but the way I see it
// Consider expecting only 1,2 or 3 as switch case
switch(x)
{
case 1:
// operations
break;
case 2:
// operations
break;
case 3:
// operations
break;
default: assert false : "Input should be between 1-3";
}
Might be convenient as any other input you might receive can be perceived as a faulty input.
Using assert false in switch block's default is applicable in the public method context e.g.
public void methA(int x) throws Exception {
if(x!=1 && x!=2 && x!=3)
throw new IllegalArgumentException("from Exception: x should be between 1,2 and 3");
switch(x)
{
case 1: doSomething(); break;
case 2: doSomething(); break;
case 3: doSomething(); break;
default: assert false : "from default: x should be between 1,2 and 3";
}
}
If the switch block is used in a public method, then checking the value of the argument x is already handled by an exception before the switch statement.
So, even when you use the assert false in default, that code is never reachable, since the assumption that x is 1,2 or 3 is always true. If not true, it is already handled by the IllegalArgumentException before the switch default. So basically, the assumption that switch-default will never be reached is always true. Hence it is appropriate in the context of public method.