Why java allows to use the labled break inside a method?
Is there any special purpose or use of this?
I thought it can be only use within the loops and swtches.
public void testMeth(int count){
label:
break label;
}
But below gives a compiler error.
public void testMeth(int count){
break; // This gives an Error : break cannot be used outside of a loop or a switch
}
I don't know the why, but the behaviour is specified in the Java Language Specification #14.15:
Break with no label
A break statement with no label attempts to transfer control to the innermost enclosing switch, while, do, or for statement of the immediately enclosing method or initializer; this statement, which is called the break target, then immediately completes normally.
If no switch, while, do, or for statement in the immediately enclosing method, constructor, or initializer contains the break statement, a compile-time error occurs.
Break with label (emphasis mine)
A break statement with label Identifier attempts to transfer control to the enclosing labeled statement (§14.7) that has the same Identifier as its label; this statement, which is called the break target, then immediately completes normally. In this case, the break target need not be a switch, while, do, or for statement.
Breaks with label enable you to redirect the code after a whole block (which can be a loop), which can be useful in the case of nested loops. It is however different from the C goto statement:
Unlike C and C++, the Java programming language has no goto statement; identifier statement labels are used with break (§14.15) or continue (§14.16) statements appearing anywhere within the labeled statement.
You can use this to break out of nested loops immediately:
out: {
for( int row=0; row< max; row++ ) {
for( int col=0; col< max; col++ )
if( row == limit) break out;
j += 1;
}
}
Using break outside of loops does not make a whole lot of sense, where would you be breaking of? To break out of a void function you can use return as adarshr points out.
You can use labeled breaks to get out of nested loops, like here.
Because there is the return statement for use outside the loops!
public void testMeth(int count){
if(count < 0) {
return;
}
// do something with count
}
I found one crazy use by my self.
public void testMeth(int count){
label: if (true) {
System.out.println("Before break");
if (count == 2) break label;
System.out.println("After break");
}
System.out.println("After IF");
}
OR
public void testMeth(int count){
namedBlock: {
System.out.println("Before break");
if (count == 0) break namedBlock;
System.out.println("After break");
}
System.out.println("After Block");
}
This ignores the "After break".
Here is yet another example of when labels are useful outside the context of a loop:
boolean cond1 = ...
if (cond1) {
boolean cond1 = ...
if (cond2) {
boolean cond3 = ...
if (cond3) {
bar();
} else {
baz();
}
} else {
baz();
}
} else {
baz();
}
...becomes...
label: {
boolean cond1 = ...
if (cond1) {
boolean cond1 = ...
if (cond2) {
boolean cond3 = ...
if (cond3) {
bar();
break label;
}
}
}
baz();
}
A contrived example, obviously, but slightly more readable. My recommendation is that if you feel the need to use a label, pretty much ever, you should otherwise refactor the code.
I strongly discurage the use of a labled break statement. It is almost as bad as a GOTO. A single break; is ok/necessary to end a loop or switch etc. But to my experience: The need for such a labled break is an indicator for a bad control-flow-design.
In most cases, a well placed exception would be more meaningful. But just, if the "Jump-Condition" can be seen as an Error. If you lable your method correctly, you can influence, what can be seen as an Error or not.
If your method is called "getDrink()" and it returns a "milk" object, it is ok. But if your method is called "getWater()", it should throw an Exception instead of returning milk...
So instead of:
public class TestBad {
public static void main(String[] args) {
String[] guys = {"hans", "john"};
myLabel: {
for(String guy: guys) {
String drink = getDrink(guy);
if(drink.equals("milk")) {
// Handle "milk"??
break myLabel;
}
// Do something with "non-milk"
}
}
// Success? Non Success??
}
private static String getDrink(String guy) {
if(guy.equals("hans"))
return "milk";
else
return "water";
}
}
You should use:
public class TestGood {
public static void main(String[] args) {
String[] guys = {"hans", "john"};
try {
handleStuff(guys);
} catch (Exception e) {
// Handle Milk here!
}
}
private static void handleStuff(String[] guys) throws Exception {
for(String guy: guys) {
String drink = getWater(guy);
// Do something with "water"
}
}
private static String getWater(String guy) throws Exception {
if(guy.equals("hans"))
// The method may NEVER return anything else than water, because of its name! So:
throw new Exception("No Water there!");
else
return "water";
}
}
Fazit: Instead of nesting Blocks into Blocks or multiple loops, one should nest methods and use proper exception handling. This enhances readability and reusability.
Related
I've tried creating a public static variable (NOT LOCAL) and purposely making an increment to it and telling Java:
"If this variable == 0, then execute this code"
so that even if that method is called the second time, that block of code won't execute because the variable has changed and is no longer zero... and it will never again be zero because it keeps increasing.
public void actionPerformed(ActionEvent e){
if(e.getSource()==deal){/*do something*/}
}
My problem is that the if statment executes more than once when I press the button "deal".
Try something like:
public class Test {
private boolean isExecuted;
public synchronized void executeOnce() {
if (isExecuted) {
return;
} else {
//do your stuff
isExecuted = true;
}
}
}
Modify it as per your requirement. To improve performance, you can use double checked locking.
Try this way, It's dummy code but through this way, you can execute inner for loop code only once.
List<WebElement> allelements = driver.findElements(By.id("id1"));
int i = 0;
for (WebElement e : allelements)
{
i++;
List<WebElement> secondelements = driver.findElements(By.id("id2"));
if(i==1)
{
for(WebElement ae : secondelements)
{
System.out.println(ae.getText());
}
}
System.out.println(e.getText());
}
So I had a previous question but realized I posted the wrong offending code. I've marked the offending statements below.
What I am trying to do is set the precedence for each of the operators with that switch statement.
Maybe someone could point me in the right direction.
Just as a note, I AM running JAVA 7 so String Switch will work.
Code
opType.java
import java.io.*;
public final class opType {
public static opType ADD = new opType( "Add" );
public static opType SUB = new opType( "Sub" );
public static opType MULT = new opType( "Mult" );
public static opType DIV = new opType( "Div" );
public static opType MOD = new opType( "Mod" );
public static opType LPAR = new opType( "LParen" );
public static opType RPAR = new opType( "RParen" );
protected String name;
private opType( String n )
{
name = n;
}
public String getName()
{
return name;
}
Operator.java
public class Operator extends Token {
protected opType val;
public boolean isOperator() { return true; }
public boolean isOperand() { return false; }
protected int getPrec()
{
switch(val.getName())
{
case "LParen":
{
return 0;
break; //unreachable
}
case "RParen":
{
return 0;
break; //unreachable
}
case "Mult":
{
return 1;
break; //unreachable
}
case "Div":
{
return 1;
break; //unreachable
}
case "Mod":
{
return 1;
break; //unreachable
}
case "Add":
{
return 2;
break; //unreachable
}
case "Sub":
{
return 2;
break; //unreachable
}
}
return 0;
}
public static int compare( Operator a, Operator b )
{
if( a.getPrec() == b.getPrec() )
return 0;
else if( a.getPrec() < b.getPrec() )
return -1;
else
return 1;
}
public opType getVal() { return val; }
public Operator( opType v ) { val = v; }
}
If you put a return, then the function returns before the break is executed and therefore the break will never be reached.
Instead you could use a variable that you set to a desired value and after the switch return that. Or just get rid of the break statements.
you already have return which will make the break unreachable
The reason that the code is unreachable is due to the return behaving like a break in that context - they both complete abruptly.
If a statement completes abruptly, then execution at that line is immediately returned to its appropriate context; if it's a break, it'll attempt to either exit the switch or return to its associated label if one exists; if it's a return, it will return to its caller, with or without a value.
This is why the code is unreachable: the line of code after the return can not be reached.
To really understand what that means or entails, we have to look at the Java Language Specification, specifically 14.1:
Every statement has a normal mode of execution in which certain
computational steps are carried out. The following sections describe
the normal mode of execution for each kind of statement.
If all the steps are carried out as described, with no indication of
abrupt completion, the statement is said to complete normally.
However, certain events may prevent a statement from completing
normally:
The break (§14.15), continue (§14.16), and return (§14.17) statements
cause a transfer of control that may prevent normal completion of
statements that contain them.
Evaluation of certain expressions may throw exceptions from the Java
Virtual Machine (§15.6). An explicit throw (§14.18) statement also
results in an exception. An exception causes a transfer of control
that may prevent normal completion of statements.
If such an event occurs, then execution of one or more statements may
be terminated before all steps of their normal mode of execution have
completed; such statements are said to complete abruptly.
An abrupt completion always has an associated reason, which is one of
the following:
A break with no label
A break with a given label
A continue with no label
A continue with a given label
A return with no value
A return with a given value
A throw with a given value, including exceptions thrown by the Java
Virtual Machine
The terms "complete normally" and "complete abruptly" also apply to
the evaluation of expressions (§15.6). The only reason an expression
can complete abruptly is that an exception is thrown, because of
either a throw with a given value (§14.18) or a run-time exception or
error (§11, §15.6).
If a statement evaluates an expression, abrupt completion of the
expression always causes the immediate abrupt completion of the
statement, with the same reason. All succeeding steps in the normal
mode of execution are not performed.
Unless otherwise specified in this chapter, abrupt completion of a
substatement causes the immediate abrupt completion of the statement
itself, with the same reason, and all succeeding steps in the normal
mode of execution of the statement are not performed.
Unless otherwise specified, a statement completes normally if all
expressions it evaluates and all substatements it executes complete
normally.
The return statement effectively exits the method immediately. Since you've placed return statements inside the switch block for each case, whichever case is matched will, according to your code, return whatever value is indicated immediately. The break therefore cannot be executed, hence the error. You have two options:
1- Set a value, and return at the end of the method:
protected int getPrec(){
int prec = 0;
switch(val.getName()) {
case "LParen":
prec = 0;
break;
case "RParen":
prec = 0;
break;
case "Mult":
prec = 1;
break;
case "Div":
prec = 1;
break;
case "Mod":
prec = 1;
break;
case "Add":
prec = 2;
break;
case "Sub":
prec = 2;
break;
default:
prec = 0;
break; // technically unnecessary since we're at the end already but adding for completeness.
}
return prec;
}
2- Ditch the break; statements and keep the return statements as you've written them.
Personally I would prefer the first option as its cleaner and more readable to me. Plus it makes it easier to expand whatever actions need to be done in one or more cases if need be in the future.
By the way, watch your naming convention. You presently have:
public final class opType // bad naming
Since this is a class, the Java standard is to capitalize the first letter of the class. So it should be:
public final class OpType // good naming
Here you can comment the line return super.onOptionsItemSelected(item)
after commenting this line the code will run.
This Works for me
public boolean onOptionsItemSelected(MenuItem item) {
//return super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case R.id.aboutUS:
Intent i = new Intent("com.code.myapp.ABOUT");
startActivity(i);
break;
case R.id.preferences:
break;
}
return false;
}
Imagine you have a Java code like this :
public class MyClass {
public static Object doSmthg(Object A,Object B){
if(smthg){ //if is given has an example, it can be any thing else
doSmthg;
GOTO label;
}
doSmthg;
label;
dosmthg1(modifying A and B);
return an Object;
}
}
I am generating the Code automatically. When the generator arrive at the moment of generating the goto (and it does not know it is in the if block), it has no knowledge of what will be afterwards.
I tried using labels,break,continue but this does not work.
I tried to use an internal class (doing dosmthg1) but A and B must be declared final. The problem is A and B have to be modified.
If there is no other solutions, I will have to propagate more knowledge in my generator. But I would prefer a simpler solution.
Any ideas ?
Thanks in advance.
public static Object doSmthg(Object A,Object B){
try {
if(smthg){ //if is given has an example, it can be any thing else
doSmthg;
throw new GotoException(1);
}
doSmthg;
} catch (GotoException e) {
e.decrementLevel();
if (e.getLevel() > 0)
throw e;
}
dosmthg1(modifying A and B);
return an Object;
}
One can do gotos with exception, but for targeting the correct "label" one either has to check the exception message or think of a nesting level.
I do not know whether I find this not uglier.
You can add a dummy loop around the block preceding the label, and use labeled break as an equivalent of goto:
public static Object doSmthg(Object A,Object B){
label:
do { // Labeled dummy loop
if(smthg){ //if is given has an example, it can be any thing else
doSmthg;
break label; // This brings you to the point after the labeled loop
}
doSmthg;
} while (false); // This is not really a loop: it goes through only once
dosmthg1(modifying A and B);
return an Object;
}
If you want to jump over something, like so:
A
if cond goto c;
B
c: C
you can do this like
while (true) {
A
if cond break;
B
}
C
I have a history in programming, but not much in software development. I'm currently writing a piece of software for the company I work at, and I've come to challenge myself on the readability of my code.
I want to know whether this is a "valid" alternative to embedded if statements, or if there is anything better I could use.
Let's say I have the following method:
public void someMethod()
{
if (some condition)
{
if (some condition 2)
{
if (some condition 3)
{
// ...etc all the way until:
doSomething();
}
else
{
System.err.println("Specific Condition 3 Error");
}
}
else
{
System.err.println("Specific Condition 2 Error");
}
}
else
{
System.err.println("Specific Condition 1 Error");
}
}
Now the first thing I should point out is that in this instance, combining the conditions (with &&) isn't possible, since each one has a unique error that I want to report, and if I combined them I wouldn't be able to do that (or would I?). The second thing I should point out before anyone screams "SWITCH STATEMENT!" at me is that not all of these conditions can be handled by a switch statement; some are Object specific method calls, some are integer comparisons, etc.
That said, is the following a valid way of making the above code more readable, or is there a better way of doing it?
public void someMethod()
{
if (!some condition)
{
System.err.println("Specific Condition 1 Error");
return;
}
if (!some condition 2)
{
System.err.println("Specific Condition 2 Error");
return;
}
if (!some condition 3)
{
System.err.println("Specific Condition 3 Error");
return;
}
doSomething();
}
So basically, instead of checking for conditions and reporting errors in else blocks, we check for the inverse of the condition and return if it is true. The result should be the same, but is there a better way of handling this?
If I was being particularly pedantic I would use something like this.
boolean c1, c2, c3;
public void someMethod() {
boolean ok = true;
String err = "";
if (ok && !(ok &= c1)) {
err = "Specific Condition 1 Error";
}
if (ok && !(ok &= c2)) {
err = "Specific Condition 2 Error";
}
if (ok && !(ok &= c3)) {
err = "Specific Condition 3 Error";
}
if ( ok ) {
doSomething();
} else {
System.out.print(err);
}
}
You are now single-exit AND flat.
Added
If &= is difficult for you, use something like:
if (ok && !c3) {
err = "Specific Condition 3 Error";
ok = false;
}
I would write it as
if (failing condition) {
System.err.println("Specific Condition 1 Error");
} else {
somethingExpensiveCondition2and3Dependon();
if (failing condition 2)
System.err.println("Specific Condition 2 Error");
else if (failing condition 3)
System.err.println("Specific Condition 3 Error");
else
doSomething();
}
yes, your code in both cases smells of conditional complexity (code smells)
Java is an OOP language, so your code should be factored to in the spirit of OOD, something like this:
for (Condition cond : conditions) {
if (cond.happens(params))
cond.getHandler().handle(params);
}
conditions list should be injected to this class, this way when a new condition is added or removed the class doesn't change. (open close principle)
Your second approach is fairly good. If you want something a little more baroque, you can move your conditions into Callable objects. Each object can also be provided with a way of handling errors. This lets you write an arbitrarily long series of tests without sacrificing functionality.
class Test {
private final Callable<Boolean> test;
private final Runnable errorHandler;
public Test(Callable<Boolean> test, Runnable handler) {
this.test = test;
errorHandler = handler;
}
public boolean runTest() {
if (test.call()) {
return true;
}
errorHandler.run();
return false;
}
}
You could then organize your code as follows:
ArrayList<Test> tests;
public void someMethod() {
for (Test test : tests) {
if (!test.runTest()) {
return;
}
}
doSomething();
}
EDIT
Here's a more general version of the above. It should handle almost any case of this type.
public class Condition {
private final Callable<Boolean> test;
private final Runnable passHandler;
private final Runnable failHandler;
public Condition(Callable<Boolean> test,
Runnable passHandler, Runnable failHandler)
{
this.test = test;
this.passHandler = passHandler;
this.failHandler = failHandler;
}
public boolean check() {
if (test.call()) {
if (passHandler != null) {
passHandler.run();
}
return true;
}
if (errorHandler != null) {
errorHandler.run();
}
return false;
}
}
public class ConditionalAction {
private final ArrayList<Condition> conditions;
private final Runnable action;
public ConditionalAction(ArrayList<Condition> conditions,
Runnable action)
{
this.conditions = conditions;
this.action = action;
}
public boolean attemptAction() {
for (Condition condition : conditions) {
if (!condition.check()) {
return false;
}
}
action.run();
return true;
}
}
One might be tempted to add some sort of generic data that could be passed around to share info or collect results. Rather than doing that, I'd recommend implementing such data sharing within the objects that implement the conditions and action, and leave this structure as is.
For this case, that's about as clean as you are going to get it, since you have both custom criteria and custom responses to each condition.
What you are in essence doing is validating some conditions before calling the doSomething() method. I would extract the validation into a separate method.
public void someMethod() {
if (isValid()) {
doSomething();
}
}
private boolean isValid() {
if (!condition1) {
System.err.println("Specific Condition 1 Error");
return false;
}
if (!condition2) {
System.err.println("Specific Condition 2 Error");
return false;
}
if (!condition3) {
System.err.println("Specific Condition 3 Error");
return false;
}
return true;
}
Nope, that's about what you get in Java. If you have too many of these, it may indicate that you should refactor a bit, and possibly even rethink your algorithm -- it may be worthwhile trying to simplify it a bit, because otherwise you're going to come back to the code in a few months and wonder why the heck a + b + c + d = e but a + b' + c + d = zebra
The second option you have is the more readable one. While multiple returns are usually not recommended putting all of them at the beginning of the code is clear (it isn't as if they are scattered all over the method). Nested ifs on the other hand, are hard to follow and understand.
public class MyTestClass {
public static void main(String[] args) {
new MyTestClass().myMethod();
}
public void myMethod(){
{
//do something
}
{
//do something
}
{
//do something
}
}//method close
}//class close
What is the benefit of doing this? I have seen this kind of code.
It is not common practice to do this kind of thing, and I wouldn't do it normally.
They are defined as Blocks in the JLS, here.
Those inner blocks ( i.e. { ... } ) can serve a couple of purposes:
Blocks limit the scope of any variables declared within them; e.g.
public void foo() {
int i = 1;
{
int j = 2;
}
// Can't refer to the "j" declared here. But can declare a new one.
int j = 3;
}
However, I wouldn't recommend doing this. IMO, it's better to use different variable names OR refactor the code into smaller methods. Either way, most Java programmers would regard the { and } as annoying visual clutter.
Blocks can be used to attach labels.
HERE : {
...
break HERE; // breaks to the statement following the block
...
}
However, in practice you hardly ever see labelled break statements. And because they are so unusual, they tend to render the code less readable.
public void stuff() {
int i = 48;
{
int i = 21;
System.out.println(i); // prints 21
}
System.out.println(i); // prints 48
}
Basically, it's a way to create scopes smaller than entire function... Benefit?.. have the people stare at your code longer before they understand it... IMO it's bad style and should be avoided