Is it ok if I omit curly braces in Java? [closed] - java

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I've searched for this, but couldn't find an answer and for whatever reason I was too ashamed to ask professor, due to that feeling when hundreds of people stare at you...
Anyhow, my question is what's the importance of having brackets? Is it OK if I omit them? Example:
for (int i = 0; i < size; i++) {
a += b;
}
vs
for (int i = 0; i < size; i++)
a += b;
I know both of them will work, but if I omit the brackets (which I tend to do a lot, due to visibility) will that change anything, anything at all? As I said, I know it works, I tested it dozen of times, but now some of my uni assignments are getting larger, and for some reason I have irrational fear that in the long run, this my cause some problems? Is there a reason to fear that?

It won't change anything at all apart from the maintainability of your code. I've seen code like this:
for (int i = 0; i < size; i++)
a += b;
System.out.println("foo");
which means this:
for (int i = 0; i < size; i++)
a += b;
System.out.println("foo");
... but which should have been this:
for (int i = 0; i < size; i++) {
a += b;
System.out.println("foo");
}
Personally I always include the brackets to reduce the possibility of confusion when reading or modifying the code.
The coding conventions at every company I've worked for have required this - which is not to say that some other companies don't have different conventions...
And just in case you think it would never make a difference: I had to fix a bug once which was pretty much equivalent to the code above. It was remarkably hard to spot... (admittedly this was years ago, before I'd started unit testing, which would no doubt have made it easier to diagnose).

Using braces makes the code more maintainable and understandable. So you should consider them by default.
I sometimes skip using braces on guard clauses to make the code more compact. My requirement for this is that they're if statements that are followed by a jump statement, like return or throw. Also, I keep them in the same line to draw attention to the idiom, e.g:.
if (!isActive()) return;
They also apply to code inside loops:
for (...) {
if (shouldSkip()) continue;
...
}
And to other jump-conditions from methods that are not necessarily at the top of the method body.
Some languages (like Perl or Ruby) have a kind of conditional statement, where braces don't apply:
return if (!isActive());
// or, more interestingly
return unless (isActive());
I consider it to be equivalent to what I just described, but explicitly supported by the language.

There is no difference. The main problem with the second version is you might end up writing this:
for (...)
do_something();
do_something_else();
when you update that method, thinking that do_something_else() is called inside the loop. (And that leads to head-scratching debug sessions.)
There is a second problem that the brace version doesn't have, and its possibly even harder to spot:
for (int i=0; i<3; i++);
System.out.println("Why on earth does this print just once?");
So keep the braces unless you have a good reason, it is just a few keystrokes more.

I think that loosing curly braces is good, if you are also using auto-format, because than your indentation is always correct, so it will be easy to spot any errors that way.
Saying that leaving the curly braces out is bad, weird or unreadable is just wrong, as whole language is based on that idea, and it's pretty popular (python).
But I have to say that without using a formatter it can be dangerous.

For most cases, the answers mentioned so far are correct. But there are some disadvantages to it from the security perspective of things. Having worked in a payments team, security is a much stronger factor that motives such decisions. Lets say you have the following code:
if( "Prod".equals(stage) )
callBankFunction ( creditCardInput )
else
callMockBankFunction ( creditCardInput )
Now lets say you have this code is not working due to some internal problem. You want to check the input. So you make the following change:
if( "Prod".equals(stage) )
callBankFunction ( creditCardInput )
else
callMockBankFunction ( creditCardInput )
Logger.log( creditCardInput )
Say you fix the problem and deploy this code (and maybe the reviewer & you think this won't cause a problem since its not inside the 'Prod' condition). Magically, your production logs now print customer credit card information that is visible to all the personnel who can see the logs. God forbid if any of them (with malicious intent) gets hold of this data.
Thus not giving a brace and a little careless coding can often lead to breach of secure information. It is also classified as a vulnerability in JAVA by CERT - Software Engineering Institure, CMU.

If you have a single statement you can omit the brackets, for more that one statements brackets is necessary for declaring a block of code.
When you use brackets you are declaring a block of code :
{
//Block of code
}
The brackets should be used also with only one statement when you are in a situation of nested statement for improve readability, so for example :
for( ; ; )
if(a == b)
doSomething()
it is more readable written with brackets also if not necessary :
for( ; ; ) {
if(a == b) {
doSomething()
}
}

If you use brackets your code is more readable.
And if you need to add some operator in same block you can avoid possible errors

Using the brackets future proofs the code against later modifications. I've seen cases where brackets were omitted and someone later added some code and didn't put the brackets in at that time. The result was that the code they added didn't go inside the section they thought it did. So I think the answer is that its good practice in light of future changes to the code. I've seen software groups adopt that as a standard, i.e. always requiring brackets even with single line blocks for that reason.

using redundant braces to claim that code is more maintainable raises the following question: if the guys writing, wondering about and further maintaining the code have issues like the ones described before (indentation related or readability related) perhaps they should not program at all...

Nowadays, it is very easy to re-indent codes to find out which block of codes is in which if or for/while. If you insist that re-indenting is hard to do, then brackets placed at wrong indentation can confuse you equally badly.
for(int i = 0; i < 100; i++) { if(i < 10) {
doSomething();
} else { for(int j = 0; j < 5; j++) {
doSomethingElse();
}
}}
If you do this everywhere, your brain is going to break down in no time. Even with brackets, you are depending on indentation to visually find the start and end of code blocks.
If indentation is important, then you should already write your code in correct indentation, so other people don't need to re-indent your codes to read correctly.
If you want to argue that the previous example is too fake/deliberate, and that the brackets are there to capture careless indentation problem (especially when you copy/paste codes), then consider this:
for(int i = 0; i < 100; i++) {
if(i < 10) {
doSomething();
}
else {
for(int j = 0; j < 5; j++) {
doSomethingElse();
}
}
Yes, it looks less serious than the previous example, but you can still get confused by such indentation.
IMHO, it is the responsibility of the person writing the code to check through the code and make sure things are indented correctly before they proceed to do other things.

More support for the "always braces" group from me. If you omit braces for single-statement loops/branches, put the statement on the same line as the control-statement,
if (condition) doSomething();
for(int i = 0; i < arr.length; ++i) arr[i] += b;
that way it's harder to forget inserting braces when the body is expanded. Still, use curlies anyway.

If you remove braces, it will only read the first line of instruction. Any additional lines will not be read. If you have more than 1 line of instruction to be executed pls use curly brace - or else exception will be thrown.

Result wise , it is the same thing.
Only two things to consider.
- Code Maintainability
- Loosely coupled code. (may execute
something else. because you haven't specified the scope for the loop. )
Note: In my observation, if it is loop with in a loop. Inner Loop without braces is also safe. Result will not vary.

If you have only one statement inside the loop it is same.
For example see the following code:
for(int i=0;i<4;i++)
System.out.println("shiva");
we have only one statement in above code. so no issue
for(int i=0;i<4;i++)
System.out.println("shiva");
System.out.println("End");
Here we are having two statements but only first statement comes into inside the loop but not the second statement.
If you have multiple statements under single loop you must use braces.

it should be a reflex to reformat the code as well... that is of course for professional programmers in professional teams

It's probably best to use the curly braces everywhere for the simple fact that debugging this would be an extreme nuisance. But other wise, one line of code doesn't necessarily need the bracket. Hope this helps!

Related

Unknown structure in java 1.6 [duplicate]

This question already has answers here:
How to use labels in java code?
(4 answers)
Should I avoid using Java Label Statements?
(12 answers)
Closed 4 years ago.
i'm working on a legacy project & i found something like that :
test:{
if(1 == 1) {
System.out.println("Oups");
break test;
}
System.out.println("Hello World");
}
I google it, but nothing seems to match with this kind of structure.
Of course, this part of code compile & run ... ????
Do someone know what that do ?
Jump-out label (Tutorial):
label: for (int i = 0; i < x; i++) {
for (int j = 0; j < i; j++) {
if (something(i, j)) break label; // jumps out of the i loop
}
}
// i.e. jumps to here
It is called label.
It is used with break to do something similar to goto in other languages.
More details you can find here
test: is called a label. Just like on a loop, the break jumps to the end of a block. The label is used to define where the break jumps to. Note the start of the scope doesn't mater provided the end is where you need it to be so really you are labelling the end not the start of the code to break to.
While it works, labels are generally too confusing with if statements, partly because they are rarely used, so I would avoid them. If you can write something with a label, you can usually write it without by using a method or in this case using an else to the if
Even using labels with loops should be avoided if you can.
This has been part of Java since version 1.0 and is still supported in Java 10.
As comments already said, this is a label that break can jump to / out of. More information here: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/branch.html

Why is it bad to change for loop counter in Java?

I often heard that it's bad to modify the loop counter in the body of a for loop. The following (bad) example shows what I am talking about.
for (int i=0; i<10; i++) {
i++;
}
I know that this would be allowed within while loops but could anybody explain why this is a bad practice in Java resp. even a problem in any programming language.
Two reasons why this is bad:
Readability. for( a; b; c ) { d; } is a shorthand for a; while( b ) { d; c; } explicitly for the case where you are iterating over a list. It is not strictly needed in the language. The whole point of having it is to imply intent: "I want to iterate over an entire list" or "I want to iterate over part of a list in sequence, then abort when I find something" at most.
If you add an additional increment, that will surprise other people encountering your code. If your c above says ++x or whatever, people will simply assume it loops over all items, just to then find "surprise! not always!".
OTOH, if you use a while loop, people only see the condition, and are alerted that this will be a more complex loop where the increment will not be constant.
Optimiziation. Given the above statement of intent, some optimizers will generate different code for a for statement than a while statement. Although none of them should generate wrong code, they might apply an optimization that has worse performance characteristics for non-sequential access than for sequential access.
And by "worse performance characteristics" I mean they may tell the CPU to cache the wrong code path and slow down your execution by a fraction of a cycle because data may have to be loaded into the CPU again after having needlessly been flushed.
Just look at what happens with this code:
1 for (int i=0; i<10; i++) {
2 i++;
3 }
Initially line 1 i=0.
Line 2 increments i, which now equals 1.
End of loop, so i++ takes effect, now i=2.
And so on ...
So if you really wanted to do something like this, you could have wrote it like:
for (int i=0; i<10; i+=2) {
}
Which gets the same result. It's not necessarily bad code, but it doesn't make sense to code like that, and it's very hard to troubleshoot.
Mainly because most of the programmers use it that way, so it is more readable for everyone as mentioned by #AntonH.
Side note: trying as in other language (like C if memory serves) to write:
for(int i =0; i< 10; i){
printf("%d", i);
i++;
}
This code compiles and run. In Java, the equivalent:
for(int i =0; i< 10; i){
System.out.println("%d", i);
i++;
}
Edited thanks to #David Wallace:This yields a compilation error, it is mandatory to have an assignement in the statement part of the for loop.

What is faster and best for with if and return or while?

I have a question about the for and while loops, as we have to travel a value until a condition is met. I wonder which is more efficient at low level, and why?
That is, these two codes give the same result:
FOR:
for (int i = 0; i<10 ; i++)
{
if (i==4)
{
return;
}
}
WHILE:
int i=0;
while (i<10 and i!=4)
{
i++;
}
This is a small example of a possible loop, and we could be looking at a record of thousands.
What code is more effective? I've always said that I have to use a while in this case, but I wonder if a low level is still better while or better yet is for.
Thank you very much.
The answer is: it doesn't matter.
You will not see any difference in performance in either, unless you really try hard to make code to see the difference, and what really matters is the readability of your code (and this is where you'll save time and and money in the future), so use whichever one is more understandable.
In your case, i'll suggest the While approach ...
I'll also suggest reading this article by Eric Lippert: How Bad Is Good Enough?, just in case you're not sold on the readability vs. silly optimizations :)
They should compile very similarly. At a low level you are looking at executing the commands within the loop, and then you will have two calls to compare a value and jump to the next block of code if the condition calls for exiting the loop.
As mentioned above, while should lead to better readability and thus is the better choice.
Both for and while are the same.
The only difference is where you place the condition.
internally the while loop uses the 'for' syntax in low level.
In your scenario. While is the best option ** if you don't know the upper limit **
you can use
While(i!=4)
{
i++
}
Use for loop if you know the upper limit, else while is the best friend.

What's the point of using labeled statements in Java? [duplicate]

This question already has answers here:
Please explain the usage of Labeled Statements
(3 answers)
Closed 7 years ago.
I'm busy studying for my certification and I stumbled upon a concept I've never even heard before - "Labeled Statements". e.g:
'label' : 'statement'
L1: while(i < 0){
L2: System.out.println(i);
}
So my question is.. why? How is this useful and when would one want to use something like this?
The only use that I'm aware of is that you can use labels in break or continue statements. So if you have nested loops, it's a way to break out of more than one level at a time:
OUTER: for (x : xList) {
for (y : yList) {
// Do something, then:
if (x > y) {
// This goes to the next iteration of x, whereas a standard
// "continue" would go to the next iteration of y
continue OUTER;
}
}
}
As the example implies, it's occasionally useful if you're iterating over two things at once in a nested fashion (e.g. searching for matches) and want to continue - or if you're doing normal iteration, but for some reason want to put a break/continue in a nested for loop.
I tend to only use them once every few years, though. There's a chicken-and-egg in that they can be hard to understand because they're a rarely-used construct, so I'll avoid using labels if the code can be clearly written in another way.
It can be used to avoid the need for a "not found" flag.
FOUND: {
for(Type t: list)
if (t.isTrue())
break FOUND;
// handle not found.
}
This is perhaps a misuse of labels, but you can use them to break without a loop.
LABEL: {
if(condition)
break LABEL;
// do something
}
It can also be used to confuse people, which is a good reason to avoid it. ;)
http://www.google.com
while(true) break http;
I used to use those as comment statements :) Jokes aside, it is like the Go to statements in basic, which allows you to jump to a line of code, ie during a deep looping structure...
Usage:
scan: {
int c;
for (firstUpper = 0 ;
firstUpper < count ;
firstUpper += Character.charCount(c)) {
c = codePointAt(firstUpper);
if (c != Character.toLowerCase(c)) {
break scan;
}
}
return this;
}
Here is an example of inordinate break that is likely to be missed out by the rest of the replies. It allows to break a loop within switch{} statement:
loop: for(;;){
int c=in.read();
switch(c){
case -1:
case '\n':
break loop;
case 'a':
processACommand();
break;
case ...
default:
break;
}
}
I think that they are required so that you can write Fortran while pretending to write Java. Without them, the aphorism Real programmers write in Fortran whatever language they are using might be invalidated.
As other answers have stated, labels are a seldom used part of the Java language.
But in your case some other things should be considered:
The labels are quite "generic" and are in fact line numbers: L1, L2, ...
The labels are not used in the code.
You are studying material for a certification.
This means, that the L1, L2 labels are simply line numbers. I assume, that the text explaining the code refers to that line numbers. In the same way some books and papers enumerate all mathematical terms just for referencing them in the text or to make citations easier.

Why does the increment/decrement in a for loop not end with a statement?

Everywhere else I write a statement in Java I need to end it with a semi-colon. However, that doesn't apply to the i++ of a for loop.
How comes?
Because it's special syntax with clear and agreed-upon semantic meaning interpretable by the compiler, because the designers of C/C++/Java/etc. arbitarily decided it should be so.
EDIT:
Some commenters have pointed out that the decision isn't really arbitary, since designers did it to maintain consistency with expression vs. statement syntax. I'm glad they pointed that out, because I didn't know that was the case. In my defense, they very clearly could have made the syntax require a semicolon in that position; the decision not to, while not entirely arbitrarily, represented a choice which could have been different. Ahem.
Because the ')' rather well terminates the update statement so it would be redundant?
Both in C and C++ it's like that, and Java copied much of the syntax of those languages, for making things easier for programmers coming from them.
Also, it really isn't necessary to end the statement with a ";", since the right parenthesis ")" demarcates where the statement ends.
I would spend some time learning the differences between an expression and a statement; as described here.
The parts of a for loop are expressions, not statements. Expressions are not terminated by semicolons. i++ is an expression. Likewise, you don't put a semicolon after the i++ here:
System.out.println(i++;);
// ^ wrong
That wouldn't make any sense. The same logic applies to if, and while loops.
If you think about it, really two of the three terms in a for loop aren't really statements. Take the canonical for loop
for(int ix = 0; ix < MAX; ix++){ /* do something */ }
that's really shorthand for
int ix = 0;
while(ix < MAX){ /* do something */ ; ix++; }
Notice that there's no semicolon for ix < MAX either. In the for loop, the semicolons are simply there to separate the terms somehow -- only by co-incidence (and a lack of extra symbols) is it the same as a statement terminator.

Categories