Should I avoid using "!" in if statement in Java? - java

Our team's Java Coding Guideline says:
Avoid using "!" in if statement as much as possible.
I have asked other colleagues, but no one gave me clear ideas why, because the guideline was created a long time ago and the author might have left our company.
Do you have any idea?

With the information provided, this calls for some speculation. One possible reason is that the intent was not for an if-statement by itself but for an if-else statement. In that case, I can see where you might say that you should reverse the cases so that you don't have the extra operation of the negation. Instead of
if (! boolVar) {
// Something
} else {
// Something else
}
you might prefer
if (boolVar) {
// Something else
} else {
// Something
}
Whether this is worth it or not is probably more a matter of taste and standardization than anything else.

The rule is likely an adaptation from Robert Martin's Clean Code, page 302:
Negatives are just a bit harder to understand than positives. So, when possible, conditionals should be expressed as positives. For example:
if(buffer.shouldCompact())
is preferable to
if(!buffer.shouldNotCompact())
As an example, suppose you're creating a validator that requires two things to be false for the entity to be valid:
The entity must not have been created within the last 12 hours, and
The entity's bank account total sum must not exceed $50,000.
Naturally the idea would be to write two methods for this:
boolean isCreatedWithinLastTwelveHours(BankAccount account)
boolean hasMoreThanTotalSumCap(BankAccount account)
...at which point, you then invoke these as:
boolean newAccount = isCreatedWithinTheLastTwelveHours(account);
boolean highEndAccount = hasMoreThanTotalSumCap(account);
if(!newAccount && !highEndAccount) { // ... other logic
// The more astute would use DeMorgan's law in an effort to make this more readable
if(!(newAccount || highEndAccount)) { // other logic
Well...wouldn't it be nicer if you just said what they weren't instead?
boolean isNotCreatedWithinLastTwelveHours(BankAccount account)
boolean hasLessThanTotalSumCap(BankAccount account)
That'd make the expression a bit more concise:
if(notNewAccount && notHighEndAccount) { // .. carry on!

Of course "!" can be used when you like. There is no "unless" in java and you have no other choices in some conditions.

Looks like yet-another-useless-rule. Generally speaking, there are no absolute terms in this scenario, true that if you are in a if-else clause then possibly it is better to write
if(myCondition) {
doThis()
} else {
doSomethingElse()
}
Instead of
if(!myCondition) {
doSomethingElse()
} else {
doThis()
}
However, that said, in some scenarios is actually quite ok to use the negation operator, particularly if no else clause is provided, example
if (!tokenDoesCompute()) {
throw InvalidTockenException("Whatever")
}
And actually in that scenario, using "!" makes quite a bit of sense for me.
Finally, if no one can really explain WHY the rule is there, maybe it is time to remove it, the only good reason I could find for it would be to provide consistency regarding the code style.

Okay, I answer my own question.
As other say, maybe this is written for the readability.
In The Art of Readable Code (p. 72) says:
Prefer dealing with the positive case first instead of the negative-e.g., if(debug) instead of if(!debug)
I found below post as well:
Readable Code - Remove Checking null
bool func(String name)
{
if ( (name != null) && (name.equals("true") ) {
//...
} else {
//...
}
}
bool func(String name)
{
if ( "true".equals(name) ) {
//...
} else {
//...
}
}

Ofcourse you can use the negation operator ! whenever you like.
However, if you have a situation where you have to write some actions in both if and else block then the following is more readable :
if(status){
//do something
}
else{
//do something else
}
than
if(!status){
//do something
}
else{
//do something else
}
But if you have situation where you only need to perform certain actions based on just one condition, i.e. if you have only an if block & no else block, then it is reasonably fine to use ! in if

I haven't seen anyone else suggest this, which is probably because they hate it as much as I do, but I'm showing it for completeness.
// Using not operator (preferred)
if (! someTest) { ... }
// Using compact not operator (kind of hides it)
if (!someTest) { ... }
// Comparing to false (ok, explicitly states what you want)
if (someTest == false) { ... }
// Comparing to true (a bit obscure)
if (someTest != true) { ... }
They all do the same, but please keep using !, just make sure you add a space after it, so it's easier to see.

Related

Return in else branch of void function

Is it good or bad practice to have an else branch which only returns in a function that returns type void? Such as this code:
public void myFunc() {
if (<some condition>) {
//run some code
} else {
return;
}
}
Note that this topic is opinion based, you will probably see many different preferences from user to user.
For readability and maintainability you should try to reduce the complexity of your code. Therefore you want to also reduce the nesting. Thus my prefered variant would be:
public void myFunc() {
// Directly leave if condition does not hold
if (!condition) {
return;
}
// Now do the rest of the code
}
If you want to stick to your current variant then I would suggest to just drop the else part because it just aggravates the readability in my opinion, so:
public void myFunc() {
if (condition) {
// Do something
}
// You can always leave a comment if you think
// that helps a reader, so you can put "Do nothing
// if condition does not hold" here
}
However as said, I personally prefer the first variant because it reduces the nesting of the overall code.
No, this else statement is not required if you are not doing any operation.
The else statement is basically used to carry out an operation, if the condition of if do not met.The best practice is not to write the else statement, if you are not doing any operation.
public void myFunc() {
if (<some condition>) {
//call FunctionA();
} else {
//call FunctionB();
}
}
In the above case, the use of else is valid. But if you are not doing any operation, then the statement is useless. Please read Clean Code Book by Robert Cecil Martin. It will help you in writing clean code.
From the java.lang.Void class documentation:
The Void class is an uninstantiable placeholder class to hold a reference to the Class object representing the Java keyword void.
So any of the following would suffice:
Parameterizing with Object and returning new Object() or null.
Parameterizing with Void and returning null.
Parameterizing with a NullObject of yours.
You can't make this method void, and anything else returns something. Since that something is ignored, you can return anything.

a nicer way for if (!true) {return;}

I have a big chuck of code witch looks like this
if(!Click(By.linkText("HR Development"))){return;}
if(!Click(By.linkText("ISTQB Agile Tester Extension ( 1/2)"))){return;}
The idea is that the Click function returns true if the click succeeds and false otherwise.
There are also other functions like this outside the click function
does someone know a nicer way to get the same result?
So why not just
return boolean_expression();
whatever that expression evaluates, gets returned.
e.g.
if (foo == bar) {
return true;
} else {
return false;
}
can simply be
return (foo == bar);
You could recast to the equivalent
if (
!Click(By.linkText("HR Development")) ||
!Click(By.linkText("ISTQB Agile Tester Extension ( 1/2)"))
){
return;
}
Note that evaluation of || stops once the result is known. (This is called short-circuitting.)
Littering your functions with many return; statements can make debugging difficult as it can become difficult to set reliable breakpoints.
I have a big chuck of code witch [sic] looks like this
That's your problem. It looks like you've written one click handling class for many events.
Another idea might be to create individual handlers for events and have custom behavior as needed. That would be a more object-oriented approach.
Just make boolean variables out your conditions, and test with a || (or) operator:
boolean foo = !Click(By.linkText("HR Development"));
boolean bar = !Click(By.linkText("ISTQB Agile Tester Extension ( 1/2)"));
if (foo || bar) {
return;
}
It's clean, and if needed, you can add as many variables as you want.

Java code PMD Complains about Cyclomatic Complexity , of 20

When i ran PMD on my Java Code , one of the Error Message it is showing is
"The class STWeb has a Cyclomatic Complexity , of 20 " .
Typically my java class is of this way
public class STWeb implements STWebService {
public String getData(RequestData request)
{
validate(request);
}
public boolean validate(Data[] formdata)
{
if(formdata.length==1)
//do this
else if(formdata.length==3)
//do this
else if(formdata.length==4)
//do this
else if(formdata.length>4)
//do this
else if(formdata.length==2)
{
if(formdata[0].getName.equals("OIY"))
{
}
/ And many more if else here
}
}
}
As you can see , as per my business requirements , i need to code the class
with many if's and if else so the reason the cyclocomplexity has ncreased , please tell me
what is feasible approach as per the standard for this ??
Cyclomatic Complexity measurements shouldn't be used for quality control, but rather as an indicator/warning for bad code. You should focus more on the code behind it rather than the value of the CC itself.
Although you can reduce the complexity of the validate method by splitting it into smaller methods through refactoring, the class as a whole will still have the same CC.
As long as the code is readable and makes sense to the next person that has to look at it, then having a higher CC shouldn't matter so much.
It helps if you have something like this:
if (a) {
return true;
} else if (b) {
return true;
} else if (c) {
return true;
} else {
return false;
}
then, you replace it with this:
return a || b || c;
Just wanted to add, that sometimes it's possible to resolve such problems with object- or structure-building. You could declare a "Wrapper-Class" for your data that is supposed to be returned. But there are always cases when you can't apply this without bloating the code with tons of objects, which in return also results in unreadable code ^^"
EDIT: this SO-post is a [nice example with ENUMS]
Cyclomatic complexity seems to indicate the amount of code paths that exist. So if your requirements say you must use many ifs and if elses, then you can ignore that message.
If this is mandatory - yes this happens despite it's futil - you can often reduce the class cyclomatic complexity by introducing base classes and move distribute the functions into the base classes until the per class cyclomatic complexity is ok.
Or simpler: add // NOPMD to your class:
public class VeryComplexStuff { // NOPMD
...

Using Return Stylishly

Let's say I had a lot of code between an if statement. Is it more proper to do a quick if-else check before it, and if it fails, return.
OR create the if statement with a lot of code in-between but not use return?
OR is it just a matter of preference?
so my 2 options are:
if(!something){
return
}
else
//lots of code here
if(something){
//lots of code here
}
From a performance perspective, you should always return from a function as quickly as you can, avoid doing unnecessary computations, "short-circuit" if you will. So checking for error cases and returning quickly would be the better policy.
Edit to add: In the same vein, you should always check the cases that are most likely to be violated first, this is sound advice when structuring your conditionals as well (|| and && checks)
I think this looks much nicer:
func() {
if(someCondition) {
return;
}
if(otherCondition) {
return;
}
//lots of code
}
than this:
func() {
if(someCondition) {
return;
} else if(otherCondition) {
return;
} else {
//lots of code
}
}
or this:
func() {
if(!someCondition) {
if(!otherCondition) {
//lots of code
}
}
}
It looks even uglier with more conditions, so I generally use the first method.
I prefer "shortcut". It has nothing to do with performance, as modern computer can handle if-else very fast, so we should focus on code readability.
However, if there's so many if-else in code, you may re-think your design. Refactory can be a better choice.
Readability and performance are not necessary conflicting constraints but when they are I tend to give readability the front seat.
To enhance readability I tend to follow the following rules.
Rule 1. Keep return as the last line of code, whatever comes in the middle. In other words don't sprinkle return statements whenever you want just because you're not too sure your if-else structure will cascade down just before the final return.
Except may be for the simplest methods I privilege a structure like
MyType func() {
MyType result ;
if ( condition ) {
result = result_1 ;
} else {
result = result_2 ;
}
return result ;
}
over an allegedly simpler
MyType func() {
if ( condition ) {
return result_1 ;
} else {
return result_2 ;
}
}
In my opinion the performance cost, if any, is negligible. However, when scaled up, I find the first coding pattern much more readable.
Rule 2. Refrain from starting a logic by "evacuating" error conditions, just in order to get them out of the way and free your mind. If your logic is well thought these checks will find their place in the logic (also have a look at guava for many well though techniques of encapsulating routine checks in helpers).
Many freshmen in my team start coding things like this
MyType func (ArgType arg1,...) {
if ( arg1 == null ) {
throw new Exception ( "hey dummy, we don't take null arg1) ;
// or return null ;
}
if ( arg2 == null ) {
// you got the picture...
}
// wow at last !!! all checks done
// Combine args and return result...
}
Which I have to say, is already a progress on just taking all conditions for granted
I tend to prefer
MyType func (ArgType arg1,...) {
MyType result ;
if ( try_to_compact_all_checks_here ) {
// Combine args and return result...
} else {
// throw, log, nullify result etc
}
return result ;
}
If the condition "try_to_compact_all_checks_here" does not fit in one line, I even sometimes prefer to get out of my way and I encapsulate all the checks in a private function. Even if it's called only once.
Rule 3. Keep the number of lines in an if/else statement to a reasonable amount (basically should fit on one screen in your IDE). To do so it is sometimes possible to extract some logic and stick it into a private function. No problem at all. All modern IDE do that for you in 2 clicks.
So basically the previous template becomes.
MyType func (ArgType arg1,...) {
MyType result ;
if ( checks_here ) {
// 1 to 20 lines max,
encapsulate lengthy logic in full fledged private methods.
} else {
// throw, log, nullify result etc
}
return result ;
}
Rule 4. Inner IFs should always have an ELSE, and that ELSE should be different from the outer ELSE.
Explanation: If I end up with
MyType func (ArgType arg1,...) {
MyType result ;
if ( check_1 ) {
if (check_2) {
Do the real work
} else {
treat error condition
}
} else {
same error condition as above
}
return result ;
}
Then it's probably because my check analysis is not complete. It happens quite often.
I try to reach
MyType func (ArgType arg1,...) {
MyType result ;
if ( check_1 && check_2) {
Do the real work
} else {
same error condition as above
}
return result ;
}
That's all.
I found that, by observing this kind of conventions, I can process large Java projects with ofter complex business logics (like in ESBs, Web Services etc), at very little performance cost if any.

Purpose of "return" statement in Scala?

Is there any real reason of providing the return statement in Scala? (aside from being more "Java-friendly")
Ignoring nested functions, it is always possible to replace Scala calculations with returns with equivalent calculations without returns. This result goes back to the early days of "structured programming", and is called the structured program theorem, cleverly enough.
With nested functions, the situation changes. Scala allows you to place a "return" buried deep inside series of nested functions. When the return is executed, control jumps out of all of the nested functions, into the the innermost containing method, from which it returns (assuming the method is actually still executing, otherwise an exception is thrown). This sort of stack-unwinding could be done with exceptions, but can't be done via a mechanical restructuring of the computation (as is possible without nested functions).
The most common reason you actually would want to return from inside a nested function is to break out of an imperative for-comprehension or resource control block. (The body of an imperative for-comprehension gets translated to a nested function, even though it looks just like a statement.)
for(i<- 1 to bezillion; j <- i to bezillion+6){
if(expensiveCalculation(i, j)){
return otherExpensiveCalculation(i, j)
}
withExpensiveResource(urlForExpensiveResource){ resource =>
// do a bunch of stuff
if(done) return
//do a bunch of other stuff
if(reallyDoneThisTime) return
//final batch of stuff
}
It is provided in order to accommodate those circumstances in which it is difficult or cumbersome to arrange all control flow paths to converge at the lexical end of the method.
While it is certainly true, as Dave Griffith says, that you can eliminate any use of return, it can often be more obfuscatory to do so than to simply cut execution short with an overt return.
Be aware, too, that return returns from methods, not function (literals) that may be defined within a method.
Here is an example
This method has lots of if-else statements to control flow, because there is no return (that is what I came with, you can use your imagination to extend it). I took this from a real life example and modified it to be a dummy code (in fact it is longer than this):
Without Return:
def process(request: Request[RawBuffer]): Result = {
if (condition1) {
error()
} else {
val condition2 = doSomethingElse()
if (!condition2) {
error()
} else {
val reply = doAnotherThing()
if (reply == null) {
Logger.warn("Receipt is null. Send bad request")
BadRequest("Coudln't receive receipt")
} else {
reply.hede = initializeHede()
if (reply.hede.isGood) {
success()
} else {
error()
}
}
}
}
}
With Return:
def process(request: Request[RawBuffer]): Result = {
if (condition1) {
return error()
}
val condition2 = doSomethingElse()
if (!condition2) {
return error()
}
val reply = doAnotherThing()
if (reply == null) {
Logger.warn("Receipt is null. Send bad request")
return BadRequest("Coudln't receive receipt")
}
reply.hede = initializeHede()
if (reply.hede.isGood)
return success()
return error()
}
To my eyes, the second one is more readable and even manageable than the first one. The depth of indentation (with well formatted code) goes deep and deep if you don't use a return statement. And I don't like it :)
I view return as a useful when writing imperative style code, which generally means I/O code. If you're doing pure functional code, you don't need (and should not use) return. But with functional code you may need laziness to get performance equivalent to imperative code that can "escape early" using return.

Categories