Switch blocks must not contain statement labelsJAVA-E1005
This switch block mixes case directives with statement labels. This is confusing at best, and in the worst case, may introduce bugs in your code.
This may have occurred due to a missing case keyword before the label.
Labels are typically used as an easy way to break out of nested control structures. For example, breaking entirely out of a loop nested in a switch block is made quite easy with a label placed just outside the switch block:
String string = new Scanner(System.in).next();
int index = new Scanner(System.in).nextInt();
outer: switch (index) {
case 1:
for (int i = index; i < string.length() - index; i++) {
if (string.charAt(index + i) != 'a') break outer; // Break out of the outer switch as well.
}
if (string.charAt(index) == 'c') break;
// else, fallthrough.
case 2: // ...
System.out.println("dfdsf");
break;
// ...
default:
};
According to the JLS, Section 14.7:
... There is no restriction against using the same identifier as a label and as the name of a package, class, interface, method, field, parameter, or local variable. ...
Bad Practice
switch (month) {
case JANUARY:
// ...
break;
case FEBRUARY:
// ...
break;
MARCH: // !!!
// ...
break;
case APRIL:
// ...
break;
// ...
default: // ...
};
In the switch block above, MARCH may have been intended as a value that would match against month. Unfortunately, because it was not marked as a case clause, MARCH will instead be interpreted as a statement label that appears as part of the FEBRUARY case clause.
switch (month) {
case JANUARY: // ...
case FEBRUARY:
loop: for (int i = MONDAY; i < SUNDAY; i++) {
if (day == i) break loop;
}
// ...
case MARCH: // ...
// ...
};
In this example, the usage of the label loop is syntactically correct and there isn't much ambiguity surrounding its usage. However, this is still a bad practice. A label is not required to break only the inner for loop here; just using break directly would achieve the same effect. Labels are only effective when it is necessary to break out of multiple nested structures, and will otherwise clutter your code.
Recommended
Make sure switch cases are properly formatted.
switch (month) {
case JANUARY:
// ...
break;
case FEBRUARY:
// ...
break;
case MARCH: // fixed.
// ...
break;
case APRIL:
// ...
break;
// ...
default: // ...
};
If you have a for loop within a switch block and want to be absolutely sure that any break statements will properly break the inner for loop, you could consider putting it in a function that is called within the switch block:
void processDay(int day) {
for (int i = MONDAY; i < SUNDAY; i++) {
if (day == i) break;
// ...
}
}
// ...
switch (month) {
case JANUARY: // ...
case FEBRUARY:
processDay(day);
// ...
case MARCH: // ...
// ...
};
References
- Java Language Specification - Section 14.7