Related
I recently rediscovered the use of breaking back to a label. Now I'm wondering if it is possible to break back to a label from another class.
Example of what i want:
Main.class
label:
for (Product p : ProductList) {
if (p.getSet() == true) {
classHandler();
}
}
Classhandler.class
someFunction() {
break label;
}
While I was typing this I actually tried making a local function in my Main class (so I could just call that function instead) but even there I got the undefined label: label error.
No, you can't. And you shouldn't.
If the condition for breaking is some problem, then throwing an exception would be the correct approach.
Otherwise you should do something like returning a flag that indicates if other products should still be handled and reacting on that in your loop.
As you noticed you can't even break through method-borders, and that's a good thing. break and continue are powerful tools, but can easily make your code confusing, if used in the wrong way. For example a break hidden inside a huge code block can be easy to miss, but if you use a continue at the very top of a method to skip an iteration based on some condition, then the intention is pretty clear.
The label that you break to must be in scope. From the java sun documentation:
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 while, do, for, or switch statement. A break
statement must refer to a label within the immediately enclosing
method or initializer block. There are no non-local jumps
No, you cannot. That does not even work between two methods of the same class. Labels are scoped (at the most) within a single method.
It doesn't make sense, since there is no guarantee that label exists, not even that someFunction() is called within a loop.
I always thought that the labels must be used only with loops but it seems not. Giving such code:
public class LabelTest {
public static void main(String[] args) {
label1: System.out.println("");
label2: LabelTest t = new LabelTest();
}
}
When compiled line labeled "label1" compiles but the code at "label2" gives errors. Why's that? And why would I want to label statements which are not "loops"?
You get an error because a label cannot be applied to variable declarations, that's just how the language grammar is defined (a label can only precede a Statement, and a LocalVariableDeclarationStatement is not a Statement). The reason is probably that it could cause confusion concerning variable scope. This works:
label1: System.out.println("");
label2: { LabelTest t = new LabelTest(); }
To add to Michael Borgwardt's answer, you can do things like this for convenience (I just discovered this the other day while reading through the Java rt.jar source code):
BlockSegment:
if (conditionIsTrue) {
doSomeProcessing ();
if (resultOfProcessingIsFalse()) break BlockSegment;
otherwiseDoSomeMoreProcessing();
// These lines get skipped if the break statement
// above gets executed
}
// This is where you resume execution after the break
anotherStatement();
Now, this is logically equivalent to:
if (conditionIsTrue) {
doSomeProcessing ();
if (!resultOfProcessingIsFalse()) {
otherwiseDoSomeMoreProcessing();
// More code here that gets executed
}
}
anotherStatement();
But, you get to skip some of the extra braces (and indentations that come with braces). Perhaps it looks cleaner (it does in my opinion), and there are some places where this style of coding may be appropriate and less confusing.
So, you may use labels beyond just loops, and even beyond if statements. For example, this is valid Java syntax (and maybe you could conjure up a reason to do something like this):
statementOne();
statementTwo();
BlockLabel: {
statementThree();
boolean result = statementFour();
if (!result) break BlockLabel;
statementFive();
statementSix();
}
statementSeven();
If the break gets executed here, then execution skips to the end of the block denoted by the label, and statementFive() and statementSix() get skipped.
The usefulness of this style (without an if statement) becomes more evident when you have blocks within blocks where you must skip around. In general, you can accomplish everything with smart enough use of loops. However, there are a few cases where labels without loops make for easier reading of code. For example, if you need to sequentially check parameters, you may either do this or throw an exception. It ends up being a matter of cleanliness of code and personal style.
It does not compile. Good question!
I have just played a little bit with your code snippet. It seems that compiler expects method call or operator after label. It does not allow assignment at this point.
I think that the fact that label is not forbidden before operators other than for, while and do is probably a bug (?!) of java compiler of specification. Anyway it is not so critical. It does not bother me (personally).
Java syntax is based on C syntax.
In C you can put a label anywhere (not just on loops) and then use goto to jump the execution to that line. Now, goto wasn't implemented in Java, but labels were left so that they can be used in combination with break or continue.
It's not that important since this isn't a standard use of labels anyway. Using labels with continue or break is bad enough (most of the times). Using them freely is also useless.
I am little late to answer this. Anyway,
label2: LabelTest t = new LabelTest(); -> Doesn't work because it is a declarative statement, as most of the above comments state the same. To make it work just do the following:
label2: new LabelTest(); // works fine
Refer to Lable in JLS
If "flag" is true I have to perform step no. 1 otherwise skip it. Is there a way out to skip this unnecessary repetitive check within the loop. (As the value of flag is not changing while the execution of the loop)
private void method(boolean flag) {
while (man > woman) {
if (flag) {
// Step no. 1
System.out.println(flag);
}
}
}
I'm not sure it is productive to worry about optimizations at this level. Generally it is more important to get the program working and move on to the next problem.
Having said that, there is an optimization called loop unswitching that some compilers will do for you. They duplicate the loop, once with and once without the conditional, and move the conditional outward to select the loop. (In your example you could make the entire loop conditional but I presume that's just an artifact of simplification for Stack Overflow.)
But this is just one more reason not to worry too much about optimizations, at least, not until you have a profile and you know that this region of code is responsible for detectable amounts of runtime.
Still, it's best to write code as cleanly as you can and puzzling through issues like this will teach you good things...
In fact, loop-invariant conditionals bother me too. I don't believe there is a general answer. There are fancy answers involving higher order functions or lambdas, "leave-it-to-the-compiler" answers, refactor-the-whole-outer-routine answers ... I would generally approve of whatever makes the code appear smaller. You have to prioritize in order to discriminate...
It depends on the scope of do. If do is always true, you don't need to check for it and you can remove if (do). There is no reason to set a variable to true if it will always be true. What is the scope?
If the value of do changes at any time in the loop, you have to check for it every time unless you rewrite the code so that the do == true state is handled outside the current loop (perhaps in a smaller loop; it depends on what you're trying to do [no pun intended]).
while (man > woman) {
Beware of infinite loops here :-)
I'm cleaning up Java code for someone who starts their functions by declaring all variables up top, and initializing them to null/0/whatever, as opposed to declaring them as they're needed later on.
What are the specific guidelines for this? Are there optimization reasons for one way or the other, or is one way just good practice? Are there any cases where it's acceptable to deviate from whatever the proper way of doing it is?
Declare variables as close to the first spot that you use them as possible. It's not really anything to do with efficiency, but makes your code much more readable. The closer a variable is declared to where it is used, the less scrolling/searching you have to do when reading the code later. Declaring variables closer to the first spot they're used will also naturally narrow their scope.
The proper way is to declare variables exactly when they are first used and minimize their scope in order to make the code easier to understand.
Declaring variables at the top of functions is a holdover from C (where it was required), and has absolutely no advantages (variable scope exists only in the source code, in the byte code all local variables exist in sequence on the stack anyway). Just don't do it, ever.
Some people may try to defend the practice by claiming that it is "neater", but any need to "organize" code within a method is usually a strong indication that the method is simply too long.
From the Java Code Conventions, Chapter 6 on Declarations:
6.3 Placement
Put declarations only at the beginning
of blocks. (A block is any code
surrounded by curly braces "{" and
"}".) Don't wait to declare variables
until their first use; it can confuse
the unwary programmer and hamper code
portability within the scope.
void myMethod() {
int int1 = 0; // beginning of method block
if (condition) {
int int2 = 0; // beginning of "if" block
...
}
}
The one exception to the rule is
indexes of for loops, which in Java
can be declared in the for statement:
for (int i = 0; i < maxLoops; i++) { ... }
Avoid local declarations that hide
declarations at higher levels. For
example, do not declare the same
variable name in an inner block:
int count;
...
myMethod() {
if (condition) {
int count = 0; // AVOID!
...
}
...
}
If you have a kabillion variables used in various isolated places down inside the body of a function, your function is too big.
If your function is a comfortably understandable size, there's no difference between "all up front" and "just as needed".
The only not-up-front variable would be in the body of a for statement.
for( Iterator i= someObject.iterator(); i.hasNext(); )
From Google Java Style Guide:
4.8.2.2 Declared when needed
Local variables are not habitually declared at the start of their
containing block or block-like construct. Instead, local variables are
declared close to the point they are first used (within reason), to
minimize their scope. Local variable declarations typically have
initializers, or are initialized immediately after declaration.
Well, I'd follow what Google does, on a superficial level it might seem that declaring all variables at the top of the method/function would be "neater", it's quite apparent that it'd be beneficial to declare variables as necessary. It's subjective though, whatever feels intuitive to you.
I've found that declaring them as-needed results in fewer mistakes than declaring them at the beginning. I've also found that declaring them at the minimum scope possible to also prevent mistakes.
When I looked at the byte-code generated by the location of the declaration few years ago, I found they were more-or-less identical. There were ocassionally differences depending on when they were assigned. Even something like:
for(Object o : list) {
Object temp = ...; //was not "redeclared" every loop iteration
}
vs
Object temp;
for(Object o : list) {
temp = ...; //nearly identical bytecoode, if not exactly identical.
}
Came out more or less identical
I am doing this very same thing at the moment. All of the variables in the code that I am reworking are declared at the top of the function. I've seen as I've been looking through this that several variables are declared but NEVER used or they are declared and operations are being done with them (ie parsing a String and then setting a Calendar object with the date/time values from the string) but then the resulting Calendar object is NEVER used.
I am going through and cleaning these up by taking the declarations from the top and moving them down in the function to a spot closer to where it is used.
Defining variable in a wider scope than needed hinders understandability quite a bit. Limited scope signals that this variable has meaning for only this small block of code and you can not think about when reading further. This is a pretty important issue because of the tiny short-term working memory that the brain has (it said that on average you can keep track of only 7 things). One less thing to keep track of is significant.
Similarly you really should try to avoid variables in the literal sense. Try to assign all things once, and declare them final so this is known to the reader. Not having to keep track whether something changes or not really cuts the cognitive load.
Principle: Place local variable declarations as close to their first use as possible, and NOT simply at the top of a method. Consider this example:
/** Return true iff s is a blah or a blub. */
public boolean checkB(String s) {
// Return true if s is a blah
... code to return true if s is a blah ...
// Return true if s is a blub. */
int helpblub= s.length() + 1;
... rest of code to return true is s is a blah.
return false;
}
Here, local variable helpblub is placed where it is necessary, in the code to test whether s is a blub. It is part of the code that implements "Return true is s is a blub".
It makes absolutely no logical sense to put the declaration of helpblub as the first statement of the method. The poor reader would wonder, why is that variable there? What is it for?
I think it is actually objectively provable that the declare-at-the-top style is more error-prone.
If you mutate-test code in either style by moving lines around at random (to simulate a merge gone bad or someone unthinkingly cut+pasting), then the declare-at-the-top style has a greater chance of compiling while functionally wrong.
I don't think declare-at-the-top has any corresponding advantage that doesn't come down to personal preference.
So assuming you want to write reliable code, learn to prefer doing just-in-time declaration.
Its a matter of readability and personal preference rather than performance. The compiler does not care and will generate the same code anyway.
I've seen people declare at the top and at the bottom of functions. I prefer the top, where I can see them quickly. It's a matter of choice and preference.
For years, I've been using named blocks to limit the scope of temporary variables. I've never seen this done anywhere else, which makes me wonder if this is a bad idea. Especially since the Eclipse IDE flags these as warnings by default.
I've used this to good effect, I think, in my own code. But since it is un-idiomatic to the point where good programmers will distrust it when they see it, I really have two ways to go from here:
avoid doing it, or
promote it, with the hope that it will become an idiom.
Example (within a larger method):
final Date nextTuesday;
initNextTuesday: {
GregorianCalendar cal = new GregorianCalendar();
... // About 5-10 lines of setting the calendar fields
nextTuesday = cal.getTime();
}
Here I'm using a GregorianCalendar just to initialize a date, and I want to make sure that I don't accidentally reuse it.
Some people have commented that you don't actually need to name the block. While that's true, a raw block looks even more like a bug, as the intent is unclear. Furthermore, naming something encourages you to think about the intention of the block. The goal here is to identify distinct sections of code, not to give every temporary variable its own scope.
Many people have commented that it's best to go straight to small methods. I agree that this should be your first instinct. However, there may be several mitigating factors:
To even consider a named block, the code should be short, one-off code that will never be called elsewhere.
A named block is a quick way to organize an oversized method without creating a one-off method with a dozen parameters. This is especially true when a class is in flux, and the inputs are likely to change from version to version.
Creating a new method encourages its reuse, which may be ill-advised if the use cases aren't well-established. A named block is easier (psychologically, at least) to throw away.
Especially for unit tests, you may need to define a dozen different objects for one-off assertions, and they are just different enough that you can't (yet) find a way to consolidate them into a small number of methods, nor can you think of a way to distinguish them with names that aren't a mile long.
Advantages of using the named scope:
Can't accidentally reuse temporary variables
Limited scope gives garbage collector and JIT compiler more information about programmer intent
Block name provides a comment on a block of code, which I find more readable than open-ended comments
Makes it easier to refactor code out of a big method into little methods, or vice versa, since the named block is easier to separate than unstructured code.
Disadvantages:
Not idiomatic: programmers who haven't seen this use of named blocks (i.e. everyone but me) assume it's buggy, since they can't find references to the block name. (Just like Eclipse does.) And getting something to become idiomatic is an uphill battle.
It can be used as an excuse for bad programming habits, such as:
Making huge, monolithic methods where several small methods would be more legible.
Layers of indentation too deep to read easily.
Note: I've edited this question extensively, based on some thoughtful responses. Thanks!
I'd just go straight for refactoring into smaller methods. If a method is big enough that it needs breaking up like this, it really needs breaking up into multiple methods if at all possible.
While limiting scope is nice, this isn't really what named blocks are for. It's unidiomatic, which is very rarely a good thing.
If this was bad, then why is this a feature in the language! It's got a purpose, and you've found it.
I often write code exactly as in your example. When you want to initialize a variable, and there's a little calculation that needs doing to work out what that should be, and that involves a couple of variables... then you don't want those variables hanging around for the entire scope of your function, then a little scope to contain the initialization works great.
Mini scopes are an easy way to break code into 'paragraphs'. If you split into methods you can make the code harder to navigate when those methods don't get called from anywhere else and have a serial kind of order in which they need to be executed.
It's always a balance, but if you think it's going to be easiest to maintain and it actually adds value to a future reader of your code if its all inline, then go for it.
There are no hard and fast rules. I get a little fed up sometimes with co-workers who excessively put everything into its own method or class or file, and this becomes a nightmare to navigate. There's a nice balance somewhere!
Sometimes I use unnamed blocks to isolate mutable things needed to prepare some immutable thing. Instead of having a label I put the Block under the immutable variable declaration.
final String example;
{
final StringBuilder sb = new StringBuilder();
for(int i = 0; i < 100; i++)
sb.append(i);
example = sb.toString();
}
When I find some other use for the block, or just think that it's in the way, I turn it into a method.
Using blocks to limit scope is a good technique in my book.
But since you're using the label to do the work of a comment, why not just use an actual comment instead? This would remove the confusion about the unreferenced label.
This is the 1st time I am seeing someone else using blocks. whew! I thought I was the only one. I know that I didn't invent it -- remembered reading it somewhere -- possibly from my previous C++ world.
I don't use the labels, though and just comment what I'm doing.
I don't agree with all the guys that are asking you extract it into a method. Most of the things we don in such blocks aren't really reusable blocks. It makes sense in a big initialization AND YES, I've used blocks to prevent COPY/PASTE errors.
BR,
~A
If you have 5-10 lines of code that can safely be put into a block like that, the same code could just as well be extracted into a method.
This might seem like it's only a semantic difference, but at least with extracting into a method then you would gain the benefit of the ability of re-use.
Just because they exist doesn't mean they should be used. Most of the advantages gained from using named blocks are better gained by using a new private method.
You won't be able to use the temporary variables declared in the new method
The GC and JIT Compiler will glean the same info by using a new method
Using a descriptive name for the new method (using "private Date initNextTuesday()" in your case) will allow for the self commenting code advantage
No need to refactor code when you have already "pre-factored" it
In addition to these benefits, you also get code reuse benefits and it will shorten your long methods.
I'd use a block with a comment rather adding a label there.
When I see a label, I can't assume that nothing else is referencing the block.
If I change the behavior of the block, then the label name may not be appropriate any more. But I can't just reach out and change it: I'll have to look through the rest of the method to determine what label is calling out to the block. At which point I'll figure out that it's an unreferenced label.
Using a comment is clearer in this instance, because it describes the behavior of the block without imposing any extra work on the part of the maintainer.
It's a good technique in my book. Managing large numbers of throwaway methods is evil and the reasons you're providing for naming the blocks are good.
What does the generated bytecode look like? That'd be my only hesitation. I suspect it strips away the block name and might even benefit from greater optimizations. But you'd have to check.
Sorry for resurrecting this, but I didn't see anyone mention what I consider to be a very important point. Let's look at your example:
final Date nextTuesday;
initNextTuesday: {
GregorianCalendar cal = new GregorianCalendar();
... // About 5-10 lines of setting the calendar fields
nextTuesday = cal.getTime();
}
Including this initialization logic here makes it easier to understand if you're reading the file from top to bottom and care about every line. But think about how you read code. Do you start reading from the top of a file and continue to the bottom? Of course not! The only time you would ever do that is during a code review. Instead, you probably have a starting point based on previous knowledge, a stack trace, etc. Then you drill further down/up through the execution path until you find what you're looking for. Optimize for reading based on execution path, not code reviews.
Does the person reading the code that uses nextTuesday really want to read about how it's initialized? I would argue that the only information that they need is that there's a Date corresponding to next Tuesday. All of this information is contained in its declaration. This is a perfect example of code that should be broken into a private method, because it isn't necessary to understand the logic that the reader cares about.
final Date nextTuesday;
initNextTuesday: {
GregorianCalendar cal = new GregorianCalendar();
//1
//2
//3
//4
//5
nextTuesday = cal.getTime();
}
vs:
final Date nextTuesday = getNextTuesday();
Which would you rather read on your way through a module?
Name Blocks helps: Using break as a Form of Goto
Using break as a civilized form of goto.
class Break {
public static void main(String args[]) {
boolean t = true;
first: {
second: {
third: {
System.out.println("Before the break.");
if (t)
break second; // break out of second block
System.out.println("This won't execute");
}
System.out.println("This won't execute");
}
System.out.println("This is after second block.");
}
}
}
Using break to exit from nested loops
class BreakLoop4 {
public static void main(String args[]) {
outer: for (int i = 0; i < 3; i++) {
System.out.print("Pass " + i + ": ");
for (int j = 0; j < 100; j++) {
if (j == 10)
break outer; // exit both loops
System.out.print(j + " ");
}
System.out.println("This will not print");
}
System.out.println("Loops complete.");
}
}
Source Link
I have done this in some of my c#. I didn't know you could name the blocks though, I'll have to try that see if it works in c# too.
I think the scope block can be a nice idea, because you can encapsulate code specific to something within a block of code, where you might not want to split it out into its own function.
As for the disadvantage of nesting them, I see that as more of a fault of a programmer not of scope blocks themselves.
Named scopes are technically ok here, it's just they aren't used in this way very often. Therefore, when someone else comes to maintain your code in the future it may not be immediately obvious why they are there. IMHO a private helper method would be a better choice...
I love the idea of using block to limit var scope.
So many times I was confused by short-lived vars given large scope which should go away immediately after use. Long method + many non-final vars make it difficult to reason about the coder's intention, especially when comments are rare. Considering much of the logic I see in a method were like below
Type foo(args..){
declare ret
...
make temp vars to add information on ret
...
make some more temp vars to add info on ret. not much related to above code. but previously declared vars are still alive
...
return ret
}
if vars can have smaller scope than the entire method body, I can quickly forget most of them (good thing).
Also I agree that too many or too few private things leads to spaghetti code.
Actually what I was looking for was something like nested method in functional languages, and seems its cousin in Java is a {BLOCK} (inner class and labmda expression are not for this..).
However, I would prefer to use a unnamed block since this may be misleading to people trying to find the reference to the label, plus I can explain better with commented block.
For using a private method, I would consider it as the next step of using blocks.