|
Java Break to Label
Statement
In this article author discusses about Java Break to
label Statement.
2005-06-30 The Java Specialists' Newsletter [Issue 110] - Break to Labeled Statement
Author:
Dr. Heinz M. Kabutz JDK version: Sun JDK 1.0 - 1.5.0_02
If you are reading this, and have not subscribed, please
consider doing it now by going to our subscribe
page. You can subscribe either via email or RSS.
Welcome to the 110th edition of The Java(tm) Specialists' Newsletter. I am back in South
Africa again, and trying to catch up with the mountain of
work that had accumulated during my international travels in
the first half of this year. I created a map
of the world showing all the countries with subscribers
to The Java(tm) Specialists' Newsletter in green. The white spaces still need colouring
in, so if you live in, e.g. Albania, Mozambique, Lesotho,
please send
send me a quick email.
Java in
Action: The Serverside was kind enough to accept
me as speaker at their conference in Orlando, Florida, in
October 2005. Please please let me know if you are going, I
would love to meet you.
We are having a rather wet start to winter down here in the
southern hemisphere. We cut down some trees last year, and
some of the logs are rather big. Helene and I are having a
running competition to see who can keep the fire burning
longer, which involves squeezing the biggest pieces into
the fireplace. She first managed for 3 days, then I kept one
burning for 5 days, even getting up at 2:00am to make sure
that there was enough wood. I think Helene is now trying to
set a new record, so I will have to be on my guard. Problem
is that we are slowly running out of wood, so we will either
have to sacrifice another tree, or buy firewood, otherwise
Helene might start burning our furniture (again :) [In case
you love trees, we only burn alien trees, such as Blue Gum
and Silky Oak.]
Talking of trees, I bought a second-hand mountain bike
last week, and have been trying to increase my level of
fitness. Last Friday morning, I cycled to Silverboomkloof
with my son Maxi, a tiny nature reserve not far from where we
live in Somerset West. This is one of the only places in the
world where the Silver Tree
Leucadendron argenteum grows. How they got
there remains a mystery, since these trees are endemic to
Table Mountain, about 50km away.
Break to Labeled Statement
Yesterday I was reading through some of the latest Java
1.5 source code, and stumbled across a snippet of code in
java.lang.String that looked rather surprising. Before we
look at it, I would like to point out that I strongly
discourage the use of break and continue.
They are leftovers from the days of C and should be avoided
since they can make your code hard to read.
public class String {
public String toLowerCase(Locale locale) {
// ...
/* Now check if there are any characters that need to be changed. */
scan: {
int c;
for (firstUpper = 0 ;
firstUpper < count ;
firstUpper += Character.charCount(c)) {
c = codePointAt(firstUpper);
if (c != Character.toLowerCase(c)) {
break scan;
}
}
return this;
}
// *snip*
}
This code struck me as bizarre. I had seen a label before a
switch and before a loop, but never a label before a code
block (i.e. an open curly brace '{').
It appears that you can write a label before any statement.
When you break to that label, you jump to the end of
that statement. There are lots of places where this does
not make sense, and you would be able to write rather weird
code, such as:
public class StrangeLabels {
public static void main(String[] args) {
what: break what; // not an infinite loop, but pointless code
what: new Runnable() { // we can define the same label twice
// we cannot access the label from in here
public void run() { }
}.run();
what: System.out.println("Hello"); // completely pointless
int i;
what: i = 42; // label on the assignment
}
}
I do not think that any of those applications of the labeled
statement break are sensible. However, you might decide to
use the labeled break to jump out of try block
without throwing an exception:
public class LabelTryFinally {
public static void main(String[] args) {
what: try {
if (true) {
break what; // you can jump out of the try block, but
// of course the finally first is executed
}
System.out.println("in try");
} finally {
System.out.println("in finally");
}
}
}
The code simply outputs "in finally" and exits.
Is there an actual use case for this code? Probably not.
I doubt that the micro-improvements (if any) in performance
would warrant cryptic code. In The
Java Language Specification, 3rd Edition, Sun give
an example on pages 388-389 that is almost impossible to
read. Even the code in java.lang.String took me a good few
minutes to understand.
Here is a way that you could use the labeled statement in the
same spirit as was used by Sun in the java.lang.String class:
/**
* Both sort functions iterate through the array to see whether
* it already is sorted. If it is, they return the original
* array, otherwise they construct a new array, copy the old
* values over sort that and return it.
*/
public class LabeledStatementBreakTest {
/**
* The approach I often see used for this type of problem.
*/
public static int[] sortWithoutBreak(int[] vals) {
// first check if the array is sorted already
boolean sorted = true;
for (int j = 1; j < vals.length && sorted; j++) {
sorted = vals[j - 1] <= vals[j];
}
if (sorted) return vals;
int[] sortedArray = new int[vals.length];
System.arraycopy(vals, 0, sortedArray, 0, vals.length);
java.util.Arrays.sort(sortedArray);
return sortedArray;
}
/**
* Using a labeled statement combined with a break to jump
* around the method.
*/
public static int[] sortWithBreak(int[] vals) {
// first check if the array is sorted already
scan: {
for (int j = 1; j < vals.length; j++) {
if (vals[j - 1] > vals[j]) break scan;
}
// sorted already
return vals;
}
int[] sortedArray = new int[vals.length];
System.arraycopy(vals, 0, sortedArray, 0, vals.length);
java.util.Arrays.sort(sortedArray);
return sortedArray;
}
/**
* This is the approach I normally use to solve this.
*/
public static int[] sortHeinz(int[] vals) {
// first check if the array is sorted already
if (isSorted(vals)) return vals;
int[] sortedArray = new int[vals.length];
System.arraycopy(vals, 0, sortedArray, 0, vals.length);
java.util.Arrays.sort(sortedArray);
return sortedArray;
}
private static boolean isSorted(int[] vals) {
for (int j = 1; j < vals.length; j++) {
if (vals[j - 1] > vals[j]) return false;
}
return true;
}
public static void main(String[] args) {
int[] vals1 = {1, 4, 5, 2, 3};
int[] vals2 = {-1, 3, 3, 5, 12, 30};
// output should always be "true"
System.out.println(vals1 != sortWithoutBreak(vals1));
System.out.println(vals2 == sortWithoutBreak(vals2));
System.out.println(vals1 != sortWithBreak(vals1));
System.out.println(vals2 == sortWithBreak(vals2));
System.out.println(vals1 != sortHeinz(vals1));
System.out.println(vals2 == sortHeinz(vals2));
}
}
This is the first time in a long time that I have seen
something in the core of the Java Programming Language
that was completely new to me.
I am visiting Johannesburg for a few days next week to
present my Java
5 course, which teaches you how to practically put in
use the new features of Java 5. I will be staying in Roodepoort, so please let me know if you are in the area and
would like to meet up for a drink after work.
Kind regards
Heinz
This material from
The Java(tm) Specialists' Newsletter by Maximum Solutions (South Africa). Please
contact Maximum Solutions for
more information.
|