Abstract: It is possible to use the break statement to jump out to the end of a labelled scope, resulting in some strange looking code, almost like the GOTO statement in C.
Welcome to the 203rd issue of The Java(tm) Specialists' Newsletter sent to you from Crete. The warm weather has suddenly arrived. Our kids are busy with wrapping up their school for the year and we are all looking forward to a break. One of the advantages of living here is that when we want to go on holiday, we are already here :-) One of my subscribers arrived from Poland today for his vacation, so we will hopefully meet up for dinner on Friday. Please remember to let me know if you head out here for your summer holidays.
After my previous newsletter on Distributed Performance Tuning, I was a bit surprised how few readers managed to ask the right question. Usually when I send out a puzzle, I get hundreds of emails. But for this one, I only received ten, of which two asked the wrong question. Of the remaining 8, exactly half had been on one of my courses and thus knew what to look for. It seems that this puzzle was a bit more difficult than most, although it really should not have been. I will discuss the answer in the next newsletter, so if you like, you can give it another try. Look at Issue 202 and also Issue 201 for some background information. Or maybe it is the time of year when programmers are lying in a hammock sipping a cocktail and not caring about Java :-)
javaspecialists.teachable.com: Please visit our new self-study course catalog to see how you can upskill your Java knowledge.
When Java was designed, they modeled the syntax on the highly popular "C" language. The strange for(;;) loop, fall-through switch statements and other weird constructs are a direct result of "C"'s influence. I think they were hoping to win the hearts of existing "C" programmers with this quirky syntax. They were successful.
From the outset, "goto" was a reserved keyword. Fortunately it was never implemented in Java, since we all know how harmful it is. However, they did implement scope-based breaks, which can cause a similar effect.
The normal way of using the "break" keyword is like this, where we "break" after every case. Without the call to "break", execution would continue and fall through to the next case:
switch(mode) { case CONNECTING: connect(); break; case SENDING: send(); break; case DISCONNECTING: disconnect(); break; default: throw new IllegalModeException(); }
However, programmers have found ways to write obscure code with labelled "break". For example, in this code, we "break" out of both for() loops by jumping to the label called "out":
out: for(int i=0; i<10; i++) { for(int j=0; j<10; j++) { if (val[i][j] == -1) break out; } }
But did you know that you could stick a label on any scope construct, and then use break to jump to the end of that scope? It is described in the Java Programming Language [ISBN 0321349806] , but thankfully, I have not witnessed this in production code. But you can do it. And this is what it would look like:
import java.util.concurrent.*; public class GoToJava { public void foo() { here: { if (ThreadLocalRandom.current().nextBoolean()) { System.out.println("First random true"); break here; } if (ThreadLocalRandom.current().nextBoolean()) { System.out.println("Second random true"); break here; } System.out.println("Both randoms false"); } System.out.println("Done"); } public static void main(String[] args) { new GoToJava().foo(); } }
I hope you all agree that this is horrible code. It might have been better if this was not allowed in Java. The code that I have seen was bad enough without these constructs.
We could generate similar code using try-finally. This is almost as obscure as the GoToJava class above, but you would probably find it marginally easier to understand, because you would have seen try-finally used in many places.
import java.util.concurrent.*; public class FinallyJava { public void foo() { try { if (ThreadLocalRandom.current().nextBoolean()) { System.out.println("First random true"); return; } if (ThreadLocalRandom.current().nextBoolean()) { System.out.println("Second random true"); return; } System.out.println("Both randoms false"); } finally { System.out.println("Done"); } } public static void main(String[] args) { new FinallyJava().foo(); } }
Remember, short methods rule. Short sentences are good too. If you write a very long sentence, regardless of how clever it might sound, your readers will eventually start getting bored and their concentration will drift, which can have the effect that, even though your writing might be poetic, your audience could fall asleep or have their minds seduced by other thoughts, which is why long sentences should probably be avoided wherever possible.
Kind regards
Heinz
We are always happy to receive comments from our readers. Feel free to send me a comment via email or discuss the newsletter in our JavaSpecialists Slack Channel (Get an invite here)
We deliver relevant courses, by top Java developers to produce more resourceful and efficient programmers within their organisations.