Correctly formulate conditions for constants? - java

I have a constant in my project, that represents some timespan. When it is below 0, I want to disable the timespan related checks.
Normally one would check
if(CONSTANT > 0) foo();
else bar();
but this causes the warning "Condition is always 'false'" or "Condition is always 'true'" depending on the value of the constant.
Is there a way to circumvent this warning, to prevent another dev to just that lines?
EDIT:
I was a bit too generic with my question. Sorry about that.
I'm having a Timer, that after some time TIME_FOR_AUTH (the constant) has passed, clears my model. This is a security measure, that makes problems while testing. Therefore I added a check, if(TIME_FOR_AUTH > 0) ... to my code.
Now I get the described warning. Since IntelliJ always asks me to delete this construct (and I'm not alone in this project), I wanted to know if there is a common practice doing that in Java / some possibility to suppress the warning.

At first, this is just a warning.
At second, you can suppress the warning using #SuppressWarnings annotation. For "is always true/false" warning, it would be #SuppressWarnings("ConstantConditions")
Code example:
package stackoverflow;
public class SuppressWarningsExample {
#SuppressWarnings("ConstantConditions")
public static void main(String[] args) {
final int value = 100;
if (value > 0)
System.out.println("Yes");
else
System.out.println("No");
}
}
For IntelliJ IDEA, you can also suppress warning per-expression with an inline // noinspection <InspectionName> comment:
// noinspection ConstantConditions
if (value > 0)
System.out.println("Yes");
else
System.out.println("No");

Here:
if(CONSTANT > 0) foo();
You say it yourself. It is a constant. Thus, right from the start, it is either bigger or smaller than 0. Thus the compiler gleefully turns the above into:
if(...x... > 0) foo();
where x would be the actual value that you assigned to CONSTANT. So right there, at compile time, this turns into
if (true)
or maybe if (false).
Long story short: rethink what you are doing. Probably you shouldn't comparing your CONSTANT, but something like:
LocalDateTime endTime = LocalDateTime.now().plusHours(1);
and then, later:
if (LocalDateTime.now().isAfter(endTime)) {
or something like that.
In other words: comparing a constant value to identify a certain condition simply doesn't much sense. Instead you can use the constant to compute some "end time", and then, over time check the current time against that "end time". Especially when using a class like LocalDateTime it is extremely easy to compute a later timestamp, as shown above.
Edit, given the edit to the question: I still suggest to NOT have such a construct in production code. Instead, I would look into means so that the test setup can configure the production in a way that allows it to effectively disable such a timeout mechanism. For example by injecting a timeout that is guaranteed to not be hit during reasonable test execution time!

Related

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.

Is there a difference in compiled Java with asserts disabled between assert someBoolean(); and verifySomeBoolean(); where latter contains an assert?

I have a postcondition I want to check regularly, across many methods. I'm fairly confident that I'm using the assert correctly, i.e. only checking something to make sure my code isn't doing anything stupid, and I intend to turn off the asserts after a while. But I'm not sure that the postcondition as I've written it now is exactly the condition I'll always want. So I put it into a method. But then I encountered the following issue:
public class Foo
{
public void doSomethingRisky()
{
//...
assert someBoolean();
}
private boolean someBoolean()
{
return bar && baz;
}
}
vs.
public class Foo
{
public void doSomethingRisky()
{
//...
verifySomeBoolean();
}
private void verifySomeBoolean()
{
assert bar && baz;
}
}
I know if I compile w/ disabled assertions, the former code will have no performance hit since someBoolean() will never get called. But is Java "smart" enough that, with assertions disabled, the second form will also have no performance hit with assertions disabled?
And the more important question, obviously, is which is better practice?
I like the assert someBoolean() because it's explicit, not subject to re- or mis-interpretation, but it seems the other form might be a little more future proof, because maybe I'll want to expand the behavior of verifySomeBoolean() to do something besides asserting the same underlying boolean. Though my gut says if that were the case, I'm better off re-coding than trying to smush the old code to fit. Any words from the wise would be much appreciated.
I thought you did not compile out assertions? I thought they were compiled and could only be enabled by the JVM with java -ea.
In that case it would be up to the JVM to optimize out an empty call when -ea is not used. But you are pre-maturely optimizing. Make the code easy to understand and write. Then optimize second. Calling an empty method is not going to cause your performance issues.
Update:
As far as style, I would go with the asserts as close to the problem as possible. I wouldn't like the assert in a method just for the check.
Second, assert() and Guava Preconditions have two different applications. assert should be used to check that your world is still the world you thought it was. It's more of a assert (1+1 == 2) type of thing. You don't use assert()'s on callee parameters. You use assert to check something you know MUST be true, but are checking it anyways.
Guava Preconditions look to be what you should be using. This is input validation and is used to check for contract compliance. Things such as: checking null argument, negative numbers when only natural numbers should be used, a properly formatted string, etc.
In summary, assert() is the "Let me just make sure gravity is still here, even though I know it is" and the Preconditions is "Let me make sure I am trying to travel faster then the police allow"

How to fix the following PMD violations

I am using PMD to analyze code and it produces a few high priority warnings which I do not know how to fix.
1) Avoid if(x!=y)..; else...; But what should I do if I need this logic? That is, I do need to check if x!=y? How can I refactor it?
2) Use explicit scoping instead of the default package private level. But the class is indeed used only within the package. What access modifier should I use?
3) Parameter is not assigned and could be declared final. Should I add final keyword to all the places which PMD pointed out with this warning?
Avoid negation: Instead of if( x!=y ) doThis() else doThat(), check for the positive case first, because people/humans tend to like positive things more than negative. It twists the brain to have to reverse the logic in mind when reading the source code. So instead, write:
if ( x!=y ) doThis() else doThat() // Bad - negation first
if ( x==y ) doThat() else doThis() // Good - positive first
Explicit scoping: According to PMD website, it's a controversial rule. You may hate it, someone else likes it. What you should do is make all the fields within your classes private. There seems to be a field or method (not a class) with a package visibility, e.g. something like this:
class Foo {
/* private missing */ Object bar;
}
Final parameters: Method parameters should be final to avoid accidental reassignment. That's just a good practice. If you're using Eclipse, the content assist even provides a quickfix called "Change modifiers to final where possible". Just select all code in the editor with Ctrl-a and then press Ctrl-1.
You don't need to enable all rules. Choose some of the rules you agree to and refactor your code until all warnings are cleared.
1 - Refactor it to a if (x == y) ... else ... logic. Just avoid negative conditions in if statments, they make code harder to understand
2 - I wouldn't enable that rule.
3 - A lot of people declare a lot of fields and variables final. Especially when they want to make sure or express that the value of a variable shall not be changed in the method. If you don't like that, disable that rule.
These all seem like minor warnings that could be turned off.
1) It wants you to flip the logic
if(x==y) {
//old else clause
} else {
//old if clause
}
2) If package is really the correct access you want, there is no access modifier to add. I am not familiar enough to know if there is a way to suppress that specific warning.
3) A style issue. Some people want final on everything it could be on. Others thinks it adds too much clutter for to little information. If you are in the latter camp, turn that warning off.
Regarding the first item (the inequality) there are two issues:
1) Readability of double negation.
Say you have:
if(x!=y) { false clause } else { true clause }
The second clause is executed if "not x is not equal to y".
This can be rewritten as:
if (x==y) {true clause } else {false clause}.
2) Correctness: if x and y are not-primitives, using if(!x.equals(y)) is safer.
This is the equivalent of using == instead of .equals() and can lead to very serious bugs.
You can also use // NOPMD at the end of any line where you don't want PMD rules to be checked.
For example for the above given code you can suppress PMD check by giving,
class Foo {
/* private missing */ Object bar; // NOPMD
}
Please be aware that the above comment may silently suppress other warnings in the same line.

extract boolean checks to local variables

Sometimes i extract boolean checks into local variables to achief better readability.
What do you think?
Any disadvantages?
Does the compiler a line-in or something if the variable isn't used anywhere else? I also thought about reducing the scope with an additional block "{}".
if (person.getAge() > MINIMUM_AGE && person.getTall() > MAXIMUM_SIZE && person.getWeight < MAXIMUM_WEIGHT) {
// do something
}
final boolean isOldEnough = person.getAge() > MINIMUM_AGE;
final boolean isTallEnough = person.getTall() > MAXIMUM_SIZE;
final boolean isNotToHeavy = person.getWeight < MAXIMUM_WEIGHT;
if (isOldEnough && isTallEnough && isNotToHeavy) {
// do something
}
I do this all the time. The code is much more readable that way. The only reason for not doing this is that it inhibits the runtime from doing shortcut optimisation, although a smart VM might figure that out.
The real risk in this approach is that it loses responsiveness to changing values.
Yes, people's age, weight, and height don't change very often, relative to the runtime of most programs, but they do change, and if, for example, age changes while the object from which your snippet is still alive, your final isOldEnough could now yield a wrong answer.
And yet I don't believe putting isEligible into Person is appropriate either, since the knowledge of what constitutes eligibility seems to be of a larger scope. One must ask: eligible for what?
All in all, in a code review, I'd probably recommend that you add methods in Person instead.
boolean isOldEnough (int minimumAge) { return (this.getAge() > minimumAge); }
And so on.
Your two blocks of code are inequivalent.
There are many cases that could be used to show this but I will use one. Suppose that person.getAge() > MINIMUM_AGE were true and person.getTall() threw an exception.
In the first case, the expression will execute the if code block, while the second case will throw an exception. In computability theory, when an exception is thrown, then this is called 'the bottom element. It has been shown that a program when evaluated using eager evaluation semantics (as in your second example), that if it terminates (does not resolve to bottom), then it is guaranteed that an evaluation strategy of laziness (your first example) is guaranteed to terminate. This is an important tenet of programming. Notice that you cannot write Java's && function yourself.
While it is unlikely that your getTall() method will throw an exception, you cannot apply your reasoning to the general case.
I think the checks probably belong in the person class. You could pass in the Min/Max values, but calling person.IsEligable() would be a better solution in my opinion.
You could go one step further and create subtypes of the Person:
Teenager extends Person
ThirdAgePerson extends Person
Kid extends Person
Subclasses will be overriding Person's methods in their own way.
One advantage to the latter case is that you will have the isOldEnough, isTallEnough, and isNotToHeavy (sic) variables available for reuse later in the code. It is also more easily readable.
You might want to consider abstracting those boolean checks into their own methods, or combining the check into a method. For example a person.isOldEnough() method which would return the value of the boolean check. You could even give it an integer parameter that would be your minimum age, to give it more flexible functionality.
I think this is a matter of personal taste. I find your refactoring quite readable.
In this particualr case I might refactor the whole test into a
isThisPersonSuitable()
method.
If there were much such code I might even create a PersonInterpreter (maybe inner) class which holds a person and answers questions about their eligibility.
Generally I would tend to favour readability over any minor performance considerations.
The only possible negative is that you lose the benefits of the AND being short-circuited. But in reality this is only really of any significance if any of your checks is largely more expensive than the others, for example if person.getWeight() was a significant operation and not just an accessor.
I have nothing against your construct, but it seems to me that in this case the readability gain could be achieved by simply putting in line breaks, i.e.
if (person.getAge() > MINIMUM_AGE
&& person.getTall() > MAXIMUM_SIZE
&& person.getWeight < MAXIMUM_WEIGHT)
{
// do something
}
The bigger issue that other answers brought up is whether this belongs inside the Person object. I think the simple answer to that is: If there are several places where you do the same test, it belongs in Person. If there are places where you do similar but different tests, then they belong in the calling class.
Like, if this is a system for a site that sells alcohol and you have many places where you must test if the person is of legal drinking age, then it makes sense to have a Person.isLegalDrinkingAge() function. If the only factor is age, then having a MINIMUM_DRINKING_AGE constant would accomplish the same result, I guess, but once there's other logic involved, like different legal drinking ages in different legal jurisdictions or there are special cases or exceptions, then it really should be a member function.
On the other hand, if you have one place where you check if someone is over 18 and somewhere else where you check if he's over 12 and somewhere else where you check if he's over 65 etc etc, then there's little to be gained by pushing this function into Person.

Should we assert every object creation in java?

Sounds like a stupid question with an obvious answer :)
Still I've ventured to ask just be doubly sure.
We are indeed using asserts like given below
ArrayList alProperties = new ArrayList();
assert alProperties != null : "alProperties is null";
Problem is that making a small & simple document to follow, on asserts is difficult. There are many books on asserts, but ideally I like to give a new programmer very simple guidelines on using something like asserts. Btw, does some tool like pmd check for proper usage of asserts?
Thanks in advance.
There's no sane reason to use asserts like that. If the object won't be created for some reason, your assert won't even be reached (because an exception was thrown or the VM exited, for example)
There are some fairly concise guidelines on using assertions in Sun's Programming with Assertions. That article advises that asserts should be used for things like Internal Invariants, Control-Flow Invariants, and Preconditions, Postconditions, and Class Invariants.
No , you don't want to check object creation.
If the object creation fails, the jvm will throw an OutOfMemoryError, and if that happens you're likely to be screwd beyond repair anyway.
that's like not trusting the JVM. Concerning what you take as a given, you got to draw a line somewhere...
This assert only clutters your code, it would be equivalent to this assert:
boolean a = true;
assert a : "A should be true"
You shouldn't be testing your JVM, unless that's the point of your program (say, it's a test suite for a JVM you are making). Instead you should be testing your pre-conditions, post-conditions and invariants. Sometimes these tests are too basic or too expensive.
Pre-conditions probably should only appear at the start of a method (if your have very long methods, then you should break that method into small parts, even if they are all private).
Post-conditions should make it clear what you have returned to the caller, you don't test that the sqrt function just returned the sqrt, but you might test that it was positive to make it clear what you are expecting (perhaps later code uses complex numbers and yours is not tested for that). Instead leave a comment at the bottom.
Invariants also often can't be tested, you can't test that your current solution is the correct partial solution (see below) -- though this is one of the nice things about writing things with tail-recursion. Instead, you declare the invariant with a comment.
If you are calling things externally, you would also use an assert, for instance in your example if you had ArrayList.Create(), then you might choose the assertion check for null. But only because you don't trust the other code. If you wrote that code, you could put the assertion (comment or otherwise) in the factory method itself.
int max(int[] a, int n) {
assert n <= a.length : "N should not exceed the bounds of the array"
assert n > 0 : "N should be at least one"
// invariant: m is the maximum of a[0..i]
int m = a[0];
for( int i = 1; i < n; n++ ) {
if( m < a[i] )
m = a[i];
}
// if these were not basic types, we might assert that we found
// something sensible here, such as m != null
return m;
}
In Java each call to new returns either a non-null reference to the new object or raises an Exception or an Error. In the first case your assert is true, in the second case the assert will not be reached, because you end in the next matching catch-block.
This assert tests if your Java-implementation is broken and in this case you can't even rely on the assert. So I would not make such asserts. Use assert for restrictions on objects, that aren't enforced by the language (for instance, if your method is passed a parameter that is null but shouldn't be).
I'm not sure of complete understand your question but i think that assertions of that kind aren't neccesary.
When you create an instance, if the program flow continue, the instance isn't a null reference.
You want ASSERTS to check properties or invariants of your program. A good document to teach this should encourage the programmer to think about such properties in a systematic/methodical manner.
if the assert fails, believe me, you're going to have bigger problems than just dealing with the assert.
If that assert fails I think it's time I look for another job because the computer is not behaving how it's supposed to and when that happens all hell is going to break loose!

Categories

Resources