Semicolon at end of 'if' statement - java

Today, after half an hour of searching for a bug, I discovered that it is possible to put a semicolon after an if statement instead of code, like this:
if(a == b);
// Do stuff
Which basically means that the stuff will be done whether a equals b or not, and the if statement has no point whatsoever. Why doesn't Java give me an error? Is there any situation in which this would be useful?

Why does it happen?
Java Language Specification says that:
The Empty Statement
An empty statement does nothing.
EmptyStatement:
;
Execution of an empty statement always completes normally
It essentially means that you want to execute empty statement if a==b
if(a == b);
What should you do:
There are two main solutions to this problem:
You can avoid problems with empty statement by using code formatter
and surrounding stuff inside if with { and }. By doing this
Your empty statement will be much more readable.
if(a == b){
;
}
You can also check tools used for static code analysis such as:
Findbugs
Checkstyle
Pmd
They can instantly highlight problems such as this one.
I would recommend to combine both solutions.

Is there any situation in which this would be useful?
Useful? As in "makes your code cleaner, clearer, faster, more maintainable"? Not at all. This is most likely poor, confusing code.
But it's not necessarily benign. Such a statement can perform actions and/or alter state due to methods which cause side effects, and optionally evaluate those methods due to short-circuiting of operators.
if( a() && b() );
Here, a() or b() may do something, and b() will only execute if a() is true.
As to why, I think the answer is simply that it would be worse to deviate from defined, expected behavior (e.g. statements like while(reader.read());) than the alternative of developers writing bad code.
Writing bad code is always possible. And just to reiterate, this would be bad code in almost any case.

A possible use case:
if (a==b);
else {
// Do something
}
Not good, but possible.
Still, I do think that the Java specification should disallow an empty if.

If you're using Eclipse, you can make it warn you about those statements:

If you use an if statement, the first statement after the if will be executed if the condition is true. If you have a block after the if (with curly braces), it counts for that whole block. If there is no block it counts for only one statement. A single semicolon is an empty statement. You could also write the code from you example like this:
if(a==b) {
;
}

It is an old leftover from the days when there was more syntactic sugar to differentiate expressions from statements.
Basically, the comma was used as the list item separator, so the semicolon was used as the "list of statements" separator. The downside is in the handling of null items in lists, and null statements in blocks.
In a list of items, Java uses the explicit keyword null, but a "null statement" is just an empty line. Allowing the existence of an empty line is a holdover from tradition inherited from C.
Why do it? Especially with an if statement when you know that no statements are being executed: Because some if statements have side effects:
int c;
if ((c = in.read()) != -1);
Yes, it is not the best example, but basically it says read a byte from the stream and do nothing. Might be useful in some corner cases, but even if this example isn't the best, it illustrates the intent. We want to feel the side-effects of the expression without accidentally executing any statements.

I can't think of an occasion where it is useful. It can be useful for loops like
while(do something);
or
for(init; do something; something else);
If you use your code formatting in your IDE regularly these sort of bugs become obvious. Some IDEs highlight this as a probable bug as well.

I'd agree with you there's no useful purpose to this for a human. I suspect it's there because it simplifies the language definition; it means that the thing that comes after an if is e same as the thing that comes after a while, for instance.

Why? It's because its easier for compiler writers. You don't have to make a special case to check for semicolons after if(cond) and has an added usage of allowing
if (cond && maybeFunc())
;// Code here I want to ignore
Even though it's actually a terrible idea to allow this. It's just easier to allow and then to add a case to check this.

Java allows an empty block any place a statement block is allowed. I am sure making this a general rule for all blocks simplifies the compiler.
I agree that this is primarily the cause of bugs that are spectacularly hard to find. I always use braces around blocks, even when there is a single statement, but Java allows you to make a block with braces at any point, so using braces can not save you from this fate. For example, I once wasted 4 hours trying find something like this:
while (condition);
{
statement;
statement;
}
The semicolon at the end of the first line was a typo, accidentally making the statement block for the while loop empty. Because the syntax is valid the program compiled and ran fine, just not the way I wanted it to. It was really hard to find.
I can think of one situation where it is very nice that you are allowed to have empty blocks, and this is something like this:
if (condition1) {
do_action_1();
}
else if (condition2) {
//nothing really to do in this case
}
else if (condition3) {
do_action2();
}
else {
do_action3();
}
In the above example, you want to be able to separate out various conditions. Remember, those conditions might be overlapping, so it is not always possible to rearrange the order. If one of the conditions really does not need anything done, then it is nice that Java allows you to have an empty block. Otherwise, the language would need some form of a "noop" method to use when you really do not want anything done.
I personally would prefer the explicit "noop" statement -- but that is not how Java is defined.

Just a FYI about the usability and what difference it makes or can make if there is a statement like that
Consider a piece of code like the following.
int a = 10;
if ((a = 50) == 50);
System.out.println("Value of a = " + a);
Clearly in this case, the if statement does change the output. So a statement like that can make a difference.
This is a situation where this could be useful or better to say have an impact on program.

if(a==b)
println("a equals b");
You can use an IF statement without {} if there is only a single line to be executed, so by using if(a==b); you are saying if they equal, execute and empty statement... So it will do nothing, and then return to your normal loop, outside of the IF block.

A few definitions from the jls explain this (chapter 14):
Blocks are Statements
As stated here, a Block is a StatementWithoutTrailingSubstatement, which in turn is a StatementNoShortIf, which is a Statement. Thus where ever any of these is required, we can insert a Block.
The if-clause
Though this is as well the case for for and while-loops, I'll use if-statements. These rules are pretty much the same. The syntactical description of if-statements can be found here.
IfThenStatement:
if ( Expression ) Statement
IfThenElseStatement:
if ( Expression ) StatementNoShortIf else Statement
IfThenElseStatementNoShortIf:
if ( Expression ) StatementNoShortIf else StatementNoShortIf
So we can use our block here.
But why does it work with ; ?
; is defined as the EmptyStatement (link), which is as well a StatementNoShortIf. So in conditional pieces of code, like if-statement and loops, we can replace a Block with a EmptyStatement, if a StatementNoShortIf or Statement is required.
Thus if(Expression)EmptyStatement works.
Why doesn't this give an error?
Pretty simple: java gives an error if it finds invalid syntax. But if(Expression)EmptyStatement is perfectly valid syntax. Instead javac gives a warning if launched with the proper parameters. The full list of warnings that can be dis-/enabled lists the warning-name empty for this purpose. So compilation with -Xlint:all or -Xlint:empty will generate a warning about this.
Your IDE should have an option to enable this kind of warning as well.
For eclipse, see #nullptr's answer. In IntelliJ, you can press Ctrl + Shift + A, enter empty body into the search field and enable the warning (marked in the image)
What is this even used for?
To be honest, there's not much use in it from a minimalistic point of view. There's usually a way to get things done without a "do nothing" command. It's rather a question of personal preferences, whether you rather use
if( a() && b() );
or
if( a() ) b();
and same would apply to other cases, in which the EmptyStatement is used. An important point to consider on this topic is readability of code. There are occasions, where code becomes more readable by using the no-op. On the other hand there are cases, where code becomes quite a lot harder to comprehend with using the EmptyStatement - the above example would count to the later IMO.

I can think of a scenario where an empty statement is required (not for if condition but for while loop).
When a program just want an explicit confirmation from the user to proceed. This may be required when the work after the user confirmation depends on some other things and user want to take control of when to proceed.
System.out.println("Enter Y to proceed. Waiting...");
System.out.println("");
while(!(new Scanner(System.in).next().equalsIgnoreCase("Y")));
System.out.println("Proceeding...");
// do the work here

look this:
int a,b,c = 0;
if(a == b){
c =1;
}
System.out.print(c);//1
so, you can write like this:
if (a == b)c=1;
but,if this code is this:
int a,b,c=0;
if (a != b){
}
if (a == b ){
c =1;
}
you can write like this:
if(a != b);
if(a == b )c=1;
so,you will know if(a != b); do noting

The semi-colon in the if indicates the termination of the if condition as in java ; is treated as the end of a statement, so the statement after if gets executed.

Semicolon at the end of,
if(a==b); simply finish the statement in single line which means ignore the result of condition and continue the execution from the next line
This code is useful, on the other hand sometime introduce bug in program, for example,
case 1.
a = 5;
b = 3;
if(a == b);
prinf("a and b are equal");
case 2.
a = 5;
b = 5;
if(a == b);
prinf("a and b are equal");
would print the same output on the screen...

While working on a programming assignment for class where I am working with a N by N grid of doodads and comparing characteristics of a random doodad to those above, below, left, and right, I found a nice use of this to prevent nested statements and potential boundary exceptions. My goal was to minimize code and keep from nesting if-statements.
if (row == 0);
else (method (grid[row][col], grid[row-1][col]));
if (row == N-1);
else (method (grid[row][col], grid[row+1][col]));
if (col == 0);
else (method (grid[row][col], grid[row][col-1]));
if (col == N-1);<br>
else (method (grid[row][col], grid[row][col+1]));
where method(Doodad a, Doodad b) does some operation between a and b.
Alternatively, you could use exception handling to avoid this syntax, but it works and works well for my application.

Related

unreachable code when trying to stop executing method if condition true [duplicate]

Today, after half an hour of searching for a bug, I discovered that it is possible to put a semicolon after an if statement instead of code, like this:
if(a == b);
// Do stuff
Which basically means that the stuff will be done whether a equals b or not, and the if statement has no point whatsoever. Why doesn't Java give me an error? Is there any situation in which this would be useful?
Why does it happen?
Java Language Specification says that:
The Empty Statement
An empty statement does nothing.
EmptyStatement:
;
Execution of an empty statement always completes normally
It essentially means that you want to execute empty statement if a==b
if(a == b);
What should you do:
There are two main solutions to this problem:
You can avoid problems with empty statement by using code formatter
and surrounding stuff inside if with { and }. By doing this
Your empty statement will be much more readable.
if(a == b){
;
}
You can also check tools used for static code analysis such as:
Findbugs
Checkstyle
Pmd
They can instantly highlight problems such as this one.
I would recommend to combine both solutions.
Is there any situation in which this would be useful?
Useful? As in "makes your code cleaner, clearer, faster, more maintainable"? Not at all. This is most likely poor, confusing code.
But it's not necessarily benign. Such a statement can perform actions and/or alter state due to methods which cause side effects, and optionally evaluate those methods due to short-circuiting of operators.
if( a() && b() );
Here, a() or b() may do something, and b() will only execute if a() is true.
As to why, I think the answer is simply that it would be worse to deviate from defined, expected behavior (e.g. statements like while(reader.read());) than the alternative of developers writing bad code.
Writing bad code is always possible. And just to reiterate, this would be bad code in almost any case.
A possible use case:
if (a==b);
else {
// Do something
}
Not good, but possible.
Still, I do think that the Java specification should disallow an empty if.
If you're using Eclipse, you can make it warn you about those statements:
If you use an if statement, the first statement after the if will be executed if the condition is true. If you have a block after the if (with curly braces), it counts for that whole block. If there is no block it counts for only one statement. A single semicolon is an empty statement. You could also write the code from you example like this:
if(a==b) {
;
}
It is an old leftover from the days when there was more syntactic sugar to differentiate expressions from statements.
Basically, the comma was used as the list item separator, so the semicolon was used as the "list of statements" separator. The downside is in the handling of null items in lists, and null statements in blocks.
In a list of items, Java uses the explicit keyword null, but a "null statement" is just an empty line. Allowing the existence of an empty line is a holdover from tradition inherited from C.
Why do it? Especially with an if statement when you know that no statements are being executed: Because some if statements have side effects:
int c;
if ((c = in.read()) != -1);
Yes, it is not the best example, but basically it says read a byte from the stream and do nothing. Might be useful in some corner cases, but even if this example isn't the best, it illustrates the intent. We want to feel the side-effects of the expression without accidentally executing any statements.
I can't think of an occasion where it is useful. It can be useful for loops like
while(do something);
or
for(init; do something; something else);
If you use your code formatting in your IDE regularly these sort of bugs become obvious. Some IDEs highlight this as a probable bug as well.
I'd agree with you there's no useful purpose to this for a human. I suspect it's there because it simplifies the language definition; it means that the thing that comes after an if is e same as the thing that comes after a while, for instance.
Why? It's because its easier for compiler writers. You don't have to make a special case to check for semicolons after if(cond) and has an added usage of allowing
if (cond && maybeFunc())
;// Code here I want to ignore
Even though it's actually a terrible idea to allow this. It's just easier to allow and then to add a case to check this.
Java allows an empty block any place a statement block is allowed. I am sure making this a general rule for all blocks simplifies the compiler.
I agree that this is primarily the cause of bugs that are spectacularly hard to find. I always use braces around blocks, even when there is a single statement, but Java allows you to make a block with braces at any point, so using braces can not save you from this fate. For example, I once wasted 4 hours trying find something like this:
while (condition);
{
statement;
statement;
}
The semicolon at the end of the first line was a typo, accidentally making the statement block for the while loop empty. Because the syntax is valid the program compiled and ran fine, just not the way I wanted it to. It was really hard to find.
I can think of one situation where it is very nice that you are allowed to have empty blocks, and this is something like this:
if (condition1) {
do_action_1();
}
else if (condition2) {
//nothing really to do in this case
}
else if (condition3) {
do_action2();
}
else {
do_action3();
}
In the above example, you want to be able to separate out various conditions. Remember, those conditions might be overlapping, so it is not always possible to rearrange the order. If one of the conditions really does not need anything done, then it is nice that Java allows you to have an empty block. Otherwise, the language would need some form of a "noop" method to use when you really do not want anything done.
I personally would prefer the explicit "noop" statement -- but that is not how Java is defined.
Just a FYI about the usability and what difference it makes or can make if there is a statement like that
Consider a piece of code like the following.
int a = 10;
if ((a = 50) == 50);
System.out.println("Value of a = " + a);
Clearly in this case, the if statement does change the output. So a statement like that can make a difference.
This is a situation where this could be useful or better to say have an impact on program.
if(a==b)
println("a equals b");
You can use an IF statement without {} if there is only a single line to be executed, so by using if(a==b); you are saying if they equal, execute and empty statement... So it will do nothing, and then return to your normal loop, outside of the IF block.
A few definitions from the jls explain this (chapter 14):
Blocks are Statements
As stated here, a Block is a StatementWithoutTrailingSubstatement, which in turn is a StatementNoShortIf, which is a Statement. Thus where ever any of these is required, we can insert a Block.
The if-clause
Though this is as well the case for for and while-loops, I'll use if-statements. These rules are pretty much the same. The syntactical description of if-statements can be found here.
IfThenStatement:
if ( Expression ) Statement
IfThenElseStatement:
if ( Expression ) StatementNoShortIf else Statement
IfThenElseStatementNoShortIf:
if ( Expression ) StatementNoShortIf else StatementNoShortIf
So we can use our block here.
But why does it work with ; ?
; is defined as the EmptyStatement (link), which is as well a StatementNoShortIf. So in conditional pieces of code, like if-statement and loops, we can replace a Block with a EmptyStatement, if a StatementNoShortIf or Statement is required.
Thus if(Expression)EmptyStatement works.
Why doesn't this give an error?
Pretty simple: java gives an error if it finds invalid syntax. But if(Expression)EmptyStatement is perfectly valid syntax. Instead javac gives a warning if launched with the proper parameters. The full list of warnings that can be dis-/enabled lists the warning-name empty for this purpose. So compilation with -Xlint:all or -Xlint:empty will generate a warning about this.
Your IDE should have an option to enable this kind of warning as well.
For eclipse, see #nullptr's answer. In IntelliJ, you can press Ctrl + Shift + A, enter empty body into the search field and enable the warning (marked in the image)
What is this even used for?
To be honest, there's not much use in it from a minimalistic point of view. There's usually a way to get things done without a "do nothing" command. It's rather a question of personal preferences, whether you rather use
if( a() && b() );
or
if( a() ) b();
and same would apply to other cases, in which the EmptyStatement is used. An important point to consider on this topic is readability of code. There are occasions, where code becomes more readable by using the no-op. On the other hand there are cases, where code becomes quite a lot harder to comprehend with using the EmptyStatement - the above example would count to the later IMO.
I can think of a scenario where an empty statement is required (not for if condition but for while loop).
When a program just want an explicit confirmation from the user to proceed. This may be required when the work after the user confirmation depends on some other things and user want to take control of when to proceed.
System.out.println("Enter Y to proceed. Waiting...");
System.out.println("");
while(!(new Scanner(System.in).next().equalsIgnoreCase("Y")));
System.out.println("Proceeding...");
// do the work here
look this:
int a,b,c = 0;
if(a == b){
c =1;
}
System.out.print(c);//1
so, you can write like this:
if (a == b)c=1;
but,if this code is this:
int a,b,c=0;
if (a != b){
}
if (a == b ){
c =1;
}
you can write like this:
if(a != b);
if(a == b )c=1;
so,you will know if(a != b); do noting
The semi-colon in the if indicates the termination of the if condition as in java ; is treated as the end of a statement, so the statement after if gets executed.
Semicolon at the end of,
if(a==b); simply finish the statement in single line which means ignore the result of condition and continue the execution from the next line
This code is useful, on the other hand sometime introduce bug in program, for example,
case 1.
a = 5;
b = 3;
if(a == b);
prinf("a and b are equal");
case 2.
a = 5;
b = 5;
if(a == b);
prinf("a and b are equal");
would print the same output on the screen...
While working on a programming assignment for class where I am working with a N by N grid of doodads and comparing characteristics of a random doodad to those above, below, left, and right, I found a nice use of this to prevent nested statements and potential boundary exceptions. My goal was to minimize code and keep from nesting if-statements.
if (row == 0);
else (method (grid[row][col], grid[row-1][col]));
if (row == N-1);
else (method (grid[row][col], grid[row+1][col]));
if (col == 0);
else (method (grid[row][col], grid[row][col-1]));
if (col == N-1);<br>
else (method (grid[row][col], grid[row][col+1]));
where method(Doodad a, Doodad b) does some operation between a and b.
Alternatively, you could use exception handling to avoid this syntax, but it works and works well for my application.

Java Nested If condition

I suddenly got a strange doubt..
I want to know whether
if(a && b) {
}
is same as
if(a) {
if(b) {
}
}
or not..
Both the cases giving me the same result. But, I'm still not feeling comfort to use the first method in my project.
Any helps??
If using If-else statement then
if loop will execute only condition is true:---
if(condition){
//execute when it is true
}
In your case you are using Two variable a and b with AND OPERATOR.
The property of AND OPERATOR is If All giving value is true then it will return true otherwise false.
If you want to use your method then
/*
check for your in a and b
both are true
*/
then your method will be execdute
if(a && b) {
//if a and b both return true(a=true,b=true)
}
It is same. In the first case compiler guarantees that second condition will not be executed if first condition returns false.
Yes they are the same as far as functionality is concerned. && is a short-circuit operator. So, in a && b, b will be evaluated only if a is evaluated to true.
Same is the case with nested if. The inner if will be executed only when outer if is evaluated to true. But the 1st one shows your intents better if you want to execute the code only when both a and b are true.
But, one difference is that, you can implement the functionality of a = true, b = false, in 2nd case by adding that functionality before the nested if starts. But, you can't do that in 1st
a && b means if a is tue and so is b, so:
if(a && b) {
}
does not leave space for indecision, it's all or nothing, only if a && b the if body will be executed, while
if(a) {
if(b) {
}
}
leaves you space to act if a, without considering b for the moment. So if you want to do some actions before checking b you can.
If you do not have anything to do just when a then the two are equal and imho the first is to prefer because it is more readable.
Yes, it's the same thing. The && operator checks if both conditions are true. If you nest your if statements like that, it amounts to the same thing since the second one will only be checked if the first one is true. Only separate them if you need something done that involves a being true but not b.
In both cases It's just short-circuiting.
in which the second argument is only executed or evaluated if the first argument does not suffice to determine the value of the expression:
The short-circuit expression x Sand y (using Sand to denote the short-circuit variety) is equivalent to the conditional expression if x then y else false; the expression x Sor y is equivalent to if x then true else y.
Coming to the syntax,The first thing (if(a && b) )which beautifies your code and and more readable.
Both conditions are same as in first one: if(a && b){ }, you are checking with && operator So, in a && b, b will be evaluated only if a is evaluated to true.
while in second case, first of all it will check value of a in outer if condition and if it satisfies then it will check value of b in inner if condition.
But fist one is more preferable.
As many have stated before me: they are technically equivalent (right down to the short-circuit semantics).
But I dare say the && operator is preferred in any situation, and that it's not just a matter of taste. The nested if is harder to read in day-to-day code with more than just control statements, and leaves more room for error.
Mostly because if(b) communicates: "the following block is only executed if b is true".
But that's not what happens! The block is only executed if a and b are true (which is exactly what the first method communicates rather elegantly). It's very easy to unintentionally pull it out of the if(a) context (any IDE has plenty of ways to shuffle code around) and create a bug.
The nested if also leaves a lot of room for horrible code later on. Wedging code between the inner and outer can make it tricky to understand which code is executed when - especially if a and b are complex expressions. And things become really nasty when somebody decides to toss in a few else-statements.. :-) There's simply no way to get into that mess with a single && operator.
Some might argue this "flexibility" is a reason to use the second method, but I'd argue there is almost always a way to rewrite that cleanly using explicit conditions. Coding is hard enough without spending all your brain cycles on control logic.
Bottom line: every Java programmer understands the semantics of the conditional-AND operator. Relying on built-in language constructs instead of rolling your own equivalents goes a long way towards maintainability and correctness.
Hope this helps.

Is using return at the start of method bad coding practice?

I have found myself using the following practice, but something inside me kind of cringes every time i use it. Basically, it's a precondition test on the parameters to determine if the actual work should be done.
public static void doSomething(List<String> things)
{
if(things == null || things.size() <= 0)
return;
//...snip... do actual work
}
It is good practice to return at the earliest opportunity.
That way the least amount of code gets executed and evaluated.
Code that does not run cannot be in error.
Furthermore it makes the function easier to read, because you do not have to deal with all the cases that do not apply anymore.
Compare the following code
private Date someMethod(Boolean test) {
Date result;
if (null == test) {
result = null
} else {
result = test ? something : other;
}
return result;
}
vs
private Date someMethod(Boolean test) {
if (null == test) {
return null
}
return test ? something : other;
}
The second one is shorter, does not need an else and does not need the temp variable.
Note that in Java the return statement exits the function right away; in other languages (e.g. Pascal) the almost equivalent code result:= something; does not return.
Because of this fact it is customary to return at many points in Java methods.
Calling this bad practice is ignoring the fact that that particular train has long since left the station in Java.
If you are going to exit a function at many points in a function anyway, it's best to exit at the earliest opportunity
It's a matter of style and personal preference. There's nothing wrong with it.
To the best of my understanding - no.
For the sake of easier debugging there should be only one return/exit point in a subroutine, method or function.
With such approach your program may become longer and less readable, but while debugging you can put a break point at the exit and always see the state of what you return. For example you can log the state of all local variables - it may be really helpful for troubleshooting.
It looks like there a two "schools" - one says "return as early as possible", whereas another one says "there should be only one return/exit point in a program".
I am a proponent of the first one, though in practice sometimes follow the second one, just to save time.
Also, do not forget about exceptions. Very often the fact that you have to return from a method early means that you are in an exceptional situation. In your example I think throwing an exception is more appropriate.
PMD seems to think so, and that you should always let your methods run to the end, however, for certain quick sanity checks, I still use premature return statements.
It does impair the readability of the method a little, but in some cases that can be better than adding yet another if statement or other means by which to run the method to the end for all cases.
There's nothing inherently wrong with it, but if it makes you cringe, you could throw an IllegalArgumentException instead. In some cases, that's more accurate. It could, however, result in a bunch of code that look this whenever you call doSomething:
try {
doSomething(myList);
} catch (IllegalArgumentException e) {}
There is no correct answer to this question, it is a matter of taste.
In the specific example above there may be better ways of enforcing a pre-condition, but I view the general pattern of multiple early returns as akin to guards in functional programming.
I personally have no issue with this style - I think it can result in cleaner code. Trying contort everything to have a single exit point can increase verbosity and reduce readability.
It's good practice. So continue with your good work.
There is nothing wrong with it. Personally, I would use else statement to execute the rest of the function, and let it return naturally.
If you want to avoid the "return" in your method : maybe you could use a subClass of Exception of your own and handle it in your method's call ?
For example :
public static void doSomething(List<String> things) throws MyExceptionIfThingsIsEmpty {
if(things == null || things.size() <= 0)
throw new MyExceptionIfThingsIsEmpty(1, "Error, the list is empty !");
//...snip... do actual work
}
Edit :
If you don't want to use the "return" statement, you could do the opposite in the if() :
if(things != null && things.size() > 0)
// do your things
If function is long (say, 20 lines or more), then, it is good to return for few error conditions in the beginning so that reader of code can focus on logic when reading rest of the function. If function is small (say 5 lines or less), then return statements in the beginning can be distracting for reader.
So, decision should be based on primarily on whether the function becomes more readable or less readable.
Java good practices say that, as often as possible, return statements should be unique and written at the end of the method. To control what you return, use a variable. However, for returning from a void method, like the example you use, what I'd do would be perform the check in a middle method used only for such purpose. Anyway, don't take this too serious - keywords like continue should never be used according to Java good practices, but they're there, inside your scope.

Why does code with successive semi-colons compile?

According to my scientific Java experimentation, int x = 0; is equivalent to int x = 0;; which is equivalent to int x = 0;;;;;;;;;;;;;;;
Why does Java allow for this? Does it have any practical application?
Are each of these just empty statements? Do they actually take up any extra processing time during runtime? (I would assume they're just optimized out?)
Do other languages do this? I'm guessing it's something inherited from C, like a lot of things in Java. Is this true?
The extra semicolons are treated as empty statements. Empty statements do nothing, so that's why Java doesn't complain about it.
As Jake King writes, you can produce empty statements to do nothing in a loop:
while (condition);
but to make it obvious, you would write
while (condition)
;
or even better:
while (condition)
/** intentionally empty */
;
or even better, as Michael Kjörling pointed out in the comment,
while (condition)
{
/** intentionally empty */
}
More often, you see it in for-statements for endless loops:
for (;;)
or only one empty statement
for (start;;)
for (;cond;)
for (;;end)
Another thing you can do, is, to write a program, once with one, and once with 2 semicolons:
public class Empty
{
public static void main (String args[])
{
System.out.println ("Just semicolons");;
}
}
Compile it, and run list the size of byte code (identic) and do an md5sum on the bytecode (identic).
So in cases, where the semantics aren't changed, it is clearly optimized away, at least for the 1.6-Oracle compiler I can say so.
Yes, they are empty statements, which don't do anything at all. They are optimized out by the compiler, but in some cases this empty statement actually does something, doing the same thing as a set of empty braces ({}). They are inherited from C syntax, but they have few uses in Java. In C, sometimes doing something like this was useful:
while (condition);
This will loop until condition is false, preventing code from progressing. However, this is discouraged in modern code, and shouldn't ever really be used in Java. However, the empty statement does count as a statement, just a useless one, so constructs like this:
if (condition);
doSomething();
....may cause somewhat baffling results. The if statement will call the empty statement, not the method, so the method will always be called. Just a caveat to keep in mind.
One thing to note is that if you do something like this:
public int foo()
{
return(0);;
}
The compiler will/may complain about an unreachable statement because there's an empty statement after a return. At least with Oracle's 1.6 sdk it does.

Using NOT operator in IF conditions

Is it really a good practice to avoid using NOT operator in IF conditions in order to make your code better readable? I heard the if (doSomething()) is better then if (!doSomething()).
It really depends on what you're trying to accomplish. If you have no else clause then if(!doSomething()) seems fine. However, if you have
if(!doSomething()) {
...
}
else {
// do something else
}
I'd probably reverse that logic to remove the ! operator and make the if clause slightly more clear.
As a general statement, its good to make your if conditionals as readable as possible. For your example, using ! is ok. the problem is when things look like
if ((a.b && c.d.e) || !f)
you might want to do something like
bool isOk = a.b;
bool isStillOk = c.d.e
bool alternateOk = !f
then your if statement is simplified to
if ( (isOk && isStillOk) || alternateOk)
It just makes the code more readable. And if you have to debug, you can debug the isOk set of vars instead of having to dig through the variables in scope. It is also helpful for dealing with NPEs -- breaking code out into simpler chunks is always good.
No, there is absolutely nothing wrong with using the ! operator in if..then..else statements.
The naming of variables, and in your example, methods is what is important. If you are using:
if(!isPerson()) { ... } // Nothing wrong with this
However:
if(!balloons()) { ... } // method is named badly
It all comes down to readability. Always aim for what is the most readable and you won't go wrong. Always try to keep your code continuous as well, for instance, look at Bill the Lizards answer.
In general, ! is a perfectly good and readable boolean logic operator. No reason not to use it unless you're simplifying by removing double negatives or applying Morgan's law.
!(!A) = A
or
!(!A | !B) = A & B
As a rule of thumb, keep the signature of your boolean return methods mnemonic and in line with convention. The problem with the scenario that #hvgotcodes proposes is that of course a.b and c.d.e are not very friendly examples to begin with. Suppose you have a Flight and a Seat class for a flight booking application. Then the condition for booking a flight could perfectly be something like
if(flight.isActive() && !seat.isTaken())
{
//book the seat
}
This perfectly readable and understandable code. You could re-define your boolean logic for the Seat class and rephrase the condition to this, though.
if(flight.isActive() && seat.isVacant())
{
//book the seat
}
Thus removing the ! operator if it really bothers you, but you'll see that it all depends on what your boolean methods mean.
try like this
if (!(a | b)) {
//blahblah
}
It's same with
if (a | b) {}
else {
// blahblah
}
I never heard of this one before.
How is
if (doSomething()) {
} else {
// blah
}
better than
if (!doSomething()) {
// blah
}
The later is more clear and concise.
Besides the ! operator can appear in complex conditions such as (!a || b). How do you avoid it then?
Use the ! operator when you need.
It is generally not a bad idea to avoid the !-operator if you have the choice. One simple reason is that it can be a source of errors, because it is possible to overlook it. More readable can be: if(conditionA==false) in some cases. This mainly plays a role if you skip the else part.
If you have an else-block anyway you should not use the negation in the if-condition.
Except for composed-conditions like this:
if(!isA() && isB() && !isNotC())
Here you have to use some sort of negation to get the desired logic.
In this case, what really is worth thinking about is the naming of the functions or variables.
Try to name them so you can often use them in simple conditions without negation.
In this case you should think about the logic of isNotC() and if it could be replaced by a method isC() if it makes sense.
Finally your example has another problem when it comes to readability which is even more serious than the question whether to use negation or not: Does the reader of the code really knows when doSomething() returns true and when false?
If it was false was it done anyway? This is a very common problem, which ends in the reader trying to find out what the return values of functions really mean.
I think a good example of a case of when to use if (!doSomething()) would be using Optional before Java 11. Java 11 added isEmpty, but before that there was only isPresent. Image you are trying to return early from a function ( a common programming best practice)
if (!option.isPresent()){
return -1;
}
would be a very common practice. Alternatively you could introduce a temporary variable yourself if you really want to avoid the ! inside the if
var isEmpty = !option.isPresent();
if (isEmpty){
return -1;
}

Categories

Resources