Assert for null check - java

It seems widely accepted that assert statements should be reserved for testing and disabled in production because errors should have been resolved by then, and enabling assertions affects performance. However surely the same could be said of null checks with if statements. Why is this code considered good for production
if(x != null) {
x.setId(idx);
if (y != null) {
if (y.id == x.id) {
x.doSth();
}
} else {
//handle error
}
} else {
//handle error
}
but this code isn't? (Assuming assertions are enabled)
try {
assert(x != null);
x.setId(idx);
assert(y != null);
if (y.id == x.id) {
x.doSth();
}
} catch (AssertionError e) {
//handle error
}
I understand using an if statement when it's expected that a variable may not be initialized. However when it's for defensive coding, assert seems more elegant and readable.
I also tested performance for each method with this:
public class AssertTest {
static final int LOOPS = 10000000;
public static void main(String[] args) {
String testStr = "";
long startNotEqualsTest = System.currentTimeMillis();
for (int i = 0; i < LOOPS; i++) {
if (testStr != null) {
testStr = System.currentTimeMillis() + "";
} else {
throw new RuntimeException("We're doomed");
}
}
long notEqualsTestDuration = System.currentTimeMillis() - startNotEqualsTest;
testStr = "";
long startAssertTest = System.currentTimeMillis();
for (int i = 0; i < LOOPS; i++) {
try {
assert(testStr != null);
testStr = System.currentTimeMillis() + "";
} catch (AssertionError e) {
throw new RuntimeException("We're doomed");
}
}
long assertTestDuration = System.currentTimeMillis() - startAssertTest;
System.out.println("Duration with if : " + notEqualsTestDuration + "ms");
System.out.println("Duration with assert : " + assertTestDuration + "ms");
}
}
Timing is about the same for both methods:
Duration with if : 1234ms
Duration with assert : 1313ms
Disabling assertions makes very little difference:
Duration with if : 1391ms
Duration with assert : 1375ms
Have I missed any compelling reasons why null checks with if conditions are preferable to assert?

Ask yourself how you would handle the null cases? What do you do if an object is null that should not be. In most of the cases it absolutely ok to not handle it, at all. Just let it produce a NullPointerException sometime later in the execution. It is very likely to be a programming error, anyway, so it's ok to be caught by an ExceptionHandler eventually writing it to the logs.
Of course, there are cases when you need to react on null objects. if-else is made for such cases. It's easy, self-explaining, every programmer knows that construct, so why not using it. assert in production is discouraged, anyway. See this post on SO, for instance. And, for my taste, it's quite cumbersome with the try/catch block.
There are other options, as well. For instance, DavidW suggested to use annotations, which is perfectly fine, as long as you make sure that these annotations are interpreted (can be an issue when migrating code, for example).
Another approach are Validator classes. For instance, the Apache Commons library has a Validate class that checks for certain conditions and would throw an appropriate exception if the condition is not fullfilled. Of course, you can write your own Validators that will throw your custom exceptions, as well. You'll end up with a short concise one-liner like
Validate.notNull(myObj)
Validate.hasEmailCorrectSyntax("foo#bar.com");
Also take a look at Java's Object.requireNotNull

Using assert at all has to presume that the -ea flag is enabled, and in many instances...it isn't. The assert will accomplish the same thing as the null checks, with the clear side-effect that if one doesn't have their environment configured in a particular way, the code will not function as they expect.
For that reason, it makes sense to eschew assert and leverage the null checks where necessary. More concisely, if one can, it's preferable to wrap everything that could be null in an Optional instance and operate on it using ifPresent (or orElseThrow since you seem to want to indicate an error if those values are null) instead.

In my experience, if x or y being null is, in fact, an error then (instead of your first example) what will be coded is:
void someFunction(AnObject x, AnObject y) {
if (x == null || y == null) {
throw new IllegalStateException("Contract violation: x and y must be non-null");
}
// rest of method can be run without null checks.
}
As I've noted in some of the discussion below, if you know up front that certain parameter values are breaking (like null or NaN in a float/double) then it makes a lot of sense to fail fast. It helps callers isolate the problem better than if a null value gets put in a Map and the NPE gets thrown on another thread, for instance.
(Note: edited to remove a contentious suggestion to use annotations.)

Related

Getter on nested objects without having NullPointerException [duplicate]

A web service returns a huge XML and I need to access deeply nested fields of it. For example:
return wsObject.getFoo().getBar().getBaz().getInt()
The problem is that getFoo(), getBar(), getBaz() may all return null.
However, if I check for null in all cases, the code becomes very verbose and hard to read. Moreover, I may miss the checks for some of the fields.
if (wsObject.getFoo() == null) return -1;
if (wsObject.getFoo().getBar() == null) return -1;
// maybe also do something with wsObject.getFoo().getBar()
if (wsObject.getFoo().getBar().getBaz() == null) return -1;
return wsObject.getFoo().getBar().getBaz().getInt();
Is it acceptable to write
try {
return wsObject.getFoo().getBar().getBaz().getInt();
} catch (NullPointerException ignored) {
return -1;
}
or would that be considered an antipattern?
Catching NullPointerException is a really problematic thing to do since they can happen almost anywhere. It's very easy to get one from a bug, catch it by accident and continue as if everything is normal, thus hiding a real problem. It's so tricky to deal with so it's best to avoid altogether. (For example, think about auto-unboxing of a null Integer.)
I suggest that you use the Optional class instead. This is often the best approach when you want to work with values that are either present or absent.
Using that you could write your code like this:
public Optional<Integer> m(Ws wsObject) {
return Optional.ofNullable(wsObject.getFoo()) // Here you get Optional.empty() if the Foo is null
.map(f -> f.getBar()) // Here you transform the optional or get empty if the Bar is null
.map(b -> b.getBaz())
.map(b -> b.getInt());
// Add this if you want to return null instead of an empty optional if any is null
// .orElse(null);
// Or this if you want to throw an exception instead
// .orElseThrow(SomeApplicationException::new);
}
Why optional?
Using Optionals instead of null for values that might be absent makes that fact very visible and clear to readers, and the type system will make sure you don't accidentally forget about it.
You also get access to methods for working with such values more conveniently, like map and orElse.
Is absence valid or error?
But also think about if it is a valid result for the intermediate methods to return null or if that is a sign of an error. If it is always an error then it's probably better throw an exception than to return a special value, or for the intermediate methods themselves to throw an exception.
Maybe more optionals?
If on the other hand absent values from the intermediate methods are valid, maybe you can switch to Optionals for them also?
Then you could use them like this:
public Optional<Integer> mo(Ws wsObject) {
return wsObject.getFoo()
.flatMap(f -> f.getBar())
.flatMap(b -> b.getBaz())
.flatMap(b -> b.getInt());
}
Why not optional?
The only reason I can think of for not using Optional is if this is in a really performance critical part of the code, and if garbage collection overhead turns out to be a problem. This is because a few Optional objects are allocated each time the code is executed, and the VM might not be able to optimize those away. In that case your original if-tests might be better.
I suggest considering Objects.requireNonNull(T obj, String message). You might build chains with a detailed message for each exception, like
requireNonNull(requireNonNull(requireNonNull(
wsObject, "wsObject is null")
.getFoo(), "getFoo() is null")
.getBar(), "getBar() is null");
I would suggest you not to use special return-values, like -1. That's not a Java style. Java has designed the mechanism of exceptions to avoid this old-fashioned way which came from the C language.
Throwing NullPointerException is not the best option too. You could provide your own exception (making it checked to guarantee that it will be handled by a user or unchecked to process it in an easier way) or use a specific exception from XML parser you are using.
Assuming the class structure is indeed out of our control, as seems to be the case, I think catching the NPE as suggested in the question is indeed a reasonable solution, unless performance is a major concern. One small improvement might be to wrap the throw/catch logic to avoid clutter:
static <T> T get(Supplier<T> supplier, T defaultValue) {
try {
return supplier.get();
} catch (NullPointerException e) {
return defaultValue;
}
}
Now you can simply do:
return get(() -> wsObject.getFoo().getBar().getBaz().getInt(), -1);
As already pointed out by Tom in the comment,
Following statement disobeys the Law of Demeter,
wsObject.getFoo().getBar().getBaz().getInt()
What you want is int and you can get it from Foo. Law of Demeter says, never talk to the strangers. For your case you can hide the actual implementation under the hood of Foo and Bar.
Now, you can create method in Foo to fetch int from Baz. Ultimately, Foo will have Bar and in Bar we can access Int without exposing Baz directly to Foo. So, null checks are probably divided to different classes and only required attributes will be shared among the classes.
My answer goes almost in the same line as #janki, but I would like to modify the code snippet slightly as below:
if (wsObject.getFoo() != null && wsObject.getFoo().getBar() != null && wsObject.getFoo().getBar().getBaz() != null)
return wsObject.getFoo().getBar().getBaz().getInt();
else
return something or throw exception;
You can add a null check for wsObject as well, if there's any chance of that object being null.
You say that some methods "may return null" but do not say in what circumstances they return null. You say you catch the NullPointerException but you do not say why you catch it. This lack of information suggests you do not have a clear understanding of what exceptions are for and why they are superior to the alternative.
Consider a class method that is meant to perform an action, but the method can not guarantee it will perform the action, because of circumstances beyond its control (which is in fact the case for all methods in Java). We call that method and it returns. The code that calls that method needs to know whether it was successful. How can it know? How can it be structured to cope with the two possibilities, of success or failure?
Using exceptions, we can write methods that have success as a post condition. If the method returns, it was successful. If it throws an exception, it had failed. This is a big win for clarity. We can write code that clearly processes the normal, success case, and move all the error handling code into catch clauses. It often transpires that the details of how or why a method was unsuccessful are not important to the caller, so the same catch clause can be used for handling several types of failure. And it often happens that a method does not need to catch exceptions at all, but can just allow them to propagate to its caller. Exceptions due to program bugs are in that latter class; few methods can react appropriately when there is a bug.
So, those methods that return null.
Does a null value indicate a bug in your code? If it does, you should not be catching the exception at all. And your code should not be trying to second guess itself. Just write what is clear and concise on the assumption that it will work. Is a chain of method calls clear and concise? Then just use them.
Does a null value indicate invalid input to your program? If it does, a NullPointerException is not an appropriate exception to throw, because conventionally it is reserved for indicating bugs. You probably want to throw a custom exception derived from IllegalArgumentException (if you want an unchecked exception) or IOException (if you want a checked exception). Is your program required to provide detailed syntax error messages when there is invalid input? If so, checking each method for a null return value then throwing an appropriate diagnostic exception is the only thing you can do. If your program need not provide detailed diagnostics, chaining the method calls together, catching any NullPointerException and then throwing your custom exception is clearest and most concise.
One of the answers claims that the chained method calls violate the Law of Demeter and thus are bad. That claim is mistaken.
When it comes to program design, there are not really any absolute rules about what is good and what is bad. There are only heuristics: rules that are right much (even almost all) of the time. Part of the skill of programming is knowing when it is OK to break those kinds of rules. So a terse assertion that "this is against rule X" is not really an answer at all. Is this one of the situations where the rule should be broken?
The Law of Demeter is really a rule about API or class interface design. When designing classes, it is useful to have a hierarchy of abstractions. You have low level classes that uses the language primitives to directly perform operations and represent objects in an abstraction that is higher level than the language primitives. You have medium level classes that delegate to the low level classes, and implement operations and representations at a higher level than the low level classes. You have high level classes that delegate to the medium level classes, and implement still higher level operations and abstractions. (I've talked about just three levels of abstraction here, but more are possible). This allows your code to express itself in terms of appropriate abstractions at each level, thereby hiding complexity. The rationale for the Law of Demeter is that if you have a chain of method calls, that suggests you have a high level class reaching in through a medium level class to deal directly with low level details, and therefore that your medium level class has not provided a medium-level abstract operation that the high level class needs. But it seems that is not the situation you have here: you did not design the classes in the chain of method calls, they are the result of some auto-generated XML serialization code (right?), and the chain of calls is not descending through an abstraction hierarchy because the des-serialized XML is all at the same level of the abstraction hierarchy (right?)?
As others have said, respecting the Law of Demeter is definitely part of the solution. Another part, wherever possible, is to change those chained methods so they cannot return null. You can avoid returning null by instead returning an empty String, an empty Collection, or some other dummy object that means or does whatever the caller would do with null.
To improve readability, you may want to use multiple variables, like
Foo theFoo;
Bar theBar;
Baz theBaz;
theFoo = wsObject.getFoo();
if ( theFoo == null ) {
// Exit.
}
theBar = theFoo.getBar();
if ( theBar == null ) {
// Exit.
}
theBaz = theBar.getBaz();
if ( theBaz == null ) {
// Exit.
}
return theBaz.getInt();
Don't catch NullPointerException. You don't know where it is coming from (I know it is not probable in your case but maybe something else threw it) and it is slow.
You want to access the specified field and for this every other field has to be not null. This is a perfect valid reason to check every field. I would probably check it in one if and then create a method for readability. As others pointed out already returning -1 is very oldschool but I don't know if you have a reason for it or not (e.g. talking to another system).
public int callService() {
...
if(isValid(wsObject)){
return wsObject.getFoo().getBar().getBaz().getInt();
}
return -1;
}
public boolean isValid(WsObject wsObject) {
if(wsObject.getFoo() != null &&
wsObject.getFoo().getBar() != null &&
wsObject.getFoo().getBar().getBaz() != null) {
return true;
}
return false;
}
Edit: It is debatable if it's disobeyes the Law Of Demeter since the WsObject is probably only a data structure (check https://stackoverflow.com/a/26021695/1528880).
If you don't want to refactor the code and you can use Java 8, it is possible to use Method references.
A simple demo first (excuse the static inner classes)
public class JavaApplication14
{
static class Baz
{
private final int _int;
public Baz(int value){ _int = value; }
public int getInt(){ return _int; }
}
static class Bar
{
private final Baz _baz;
public Bar(Baz baz){ _baz = baz; }
public Baz getBar(){ return _baz; }
}
static class Foo
{
private final Bar _bar;
public Foo(Bar bar){ _bar = bar; }
public Bar getBar(){ return _bar; }
}
static class WSObject
{
private final Foo _foo;
public WSObject(Foo foo){ _foo = foo; }
public Foo getFoo(){ return _foo; }
}
interface Getter<T, R>
{
R get(T value);
}
static class GetterResult<R>
{
public R result;
public int lastIndex;
}
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
WSObject wsObject = new WSObject(new Foo(new Bar(new Baz(241))));
WSObject wsObjectNull = new WSObject(new Foo(null));
GetterResult<Integer> intResult
= getterChain(wsObject, WSObject::getFoo, Foo::getBar, Bar::getBar, Baz::getInt);
GetterResult<Integer> intResult2
= getterChain(wsObjectNull, WSObject::getFoo, Foo::getBar, Bar::getBar, Baz::getInt);
System.out.println(intResult.result);
System.out.println(intResult.lastIndex);
System.out.println();
System.out.println(intResult2.result);
System.out.println(intResult2.lastIndex);
// TODO code application logic here
}
public static <R, V1, V2, V3, V4> GetterResult<R>
getterChain(V1 value, Getter<V1, V2> g1, Getter<V2, V3> g2, Getter<V3, V4> g3, Getter<V4, R> g4)
{
GetterResult result = new GetterResult<>();
Object tmp = value;
if (tmp == null)
return result;
tmp = g1.get((V1)tmp);
result.lastIndex++;
if (tmp == null)
return result;
tmp = g2.get((V2)tmp);
result.lastIndex++;
if (tmp == null)
return result;
tmp = g3.get((V3)tmp);
result.lastIndex++;
if (tmp == null)
return result;
tmp = g4.get((V4)tmp);
result.lastIndex++;
result.result = (R)tmp;
return result;
}
}
Output
241
4
null
2
The interface Getter is just a functional interface, you may use any equivalent.
GetterResult class, accessors stripped out for clarity, hold the result of the getter chain, if any, or the index of the last getter called.
The method getterChain is a simple, boilerplate piece of code, that can be generated automatically (or manually when needed).
I structured the code so that the repeating block is self evident.
This is not a perfect solution as you still need to define one overload of getterChain per number of getters.
I would refactor the code instead, but if can't and you find your self using long getter chains often you may consider building a class with the overloads that take from 2 to, say, 10, getters.
I'd like to add an answer which focus on the meaning of the error. Null exception in itself doesn't provide any meaning full error. So I'd advise to avoid dealing with them directly.
There is a thousands cases where your code can go wrong: cannot connect to database, IO Exception, Network error... If you deal with them one by one (like the null check here), it would be too much of a hassle.
In the code:
wsObject.getFoo().getBar().getBaz().getInt();
Even when you know which field is null, you have no idea about what goes wrong. Maybe Bar is null, but is it expected? Or is it a data error? Think about people who read your code
Like in xenteros's answer, I'd propose using custom unchecked exception. For example, in this situation: Foo can be null (valid data), but Bar and Baz should never be null (invalid data)
The code can be re-written:
void myFunction()
{
try
{
if (wsObject.getFoo() == null)
{
throw new FooNotExistException();
}
return wsObject.getFoo().getBar().getBaz().getInt();
}
catch (Exception ex)
{
log.error(ex.Message, ex); // Write log to track whatever exception happening
throw new OperationFailedException("The requested operation failed")
}
}
void Main()
{
try
{
myFunction();
}
catch(FooNotExistException)
{
// Show error: "Your foo does not exist, please check"
}
catch(OperationFailedException)
{
// Show error: "Operation failed, please contact our support"
}
}
NullPointerException is a run-time exception, so generally speaking is not recommended to catch it, but to avoid it.
You will have to catch the exception wherever you want to call the method (or it will propagate up the stack). Nevertheless, if in your case you can keep working with that result with value -1 and you are sure that it won't propagate because you are not using any of the "pieces" that may be null, then it seems right to me to catch it
Edit:
I agree with the later answer from #xenteros, it wil be better to launch your own exception instead returning -1 you can call it InvalidXMLException for instance.
Have been following this post since yesterday.
I have been commenting/voting the comments which says, catching NPE is bad. Here is why I have been doing that.
package com.todelete;
public class Test {
public static void main(String[] args) {
Address address = new Address();
address.setSomeCrap(null);
Person person = new Person();
person.setAddress(address);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
try {
System.out.println(person.getAddress().getSomeCrap().getCrap());
} catch (NullPointerException npe) {
}
}
long endTime = System.currentTimeMillis();
System.out.println((endTime - startTime) / 1000F);
long startTime1 = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
if (person != null) {
Address address1 = person.getAddress();
if (address1 != null) {
SomeCrap someCrap2 = address1.getSomeCrap();
if (someCrap2 != null) {
System.out.println(someCrap2.getCrap());
}
}
}
}
long endTime1 = System.currentTimeMillis();
System.out.println((endTime1 - startTime1) / 1000F);
}
}
public class Person {
private Address address;
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
package com.todelete;
public class Address {
private SomeCrap someCrap;
public SomeCrap getSomeCrap() {
return someCrap;
}
public void setSomeCrap(SomeCrap someCrap) {
this.someCrap = someCrap;
}
}
package com.todelete;
public class SomeCrap {
private String crap;
public String getCrap() {
return crap;
}
public void setCrap(String crap) {
this.crap = crap;
}
}
Output
3.216
0.002
I see a clear winner here. Having if checks is way too less expensive than catch an exception. I have seen that Java-8 way of doing. Considering that 70% of the current applications still run on Java-7 I am adding this answer.
Bottom Line For any mission critical applications, handling NPE is costly.
If efficiency is an issue then the 'catch' option should be considered.
If 'catch' cannot be used because it would propagate (as mentioned by 'SCouto') then use local variables to avoid multiple calls to methods getFoo(), getBar() and getBaz().
It's worth considering to create your own Exception. Let's call it MyOperationFailedException. You can throw it instead returning a value. The result will be the same - you'll quit the function, but you won't return hard-coded value -1 which is Java anti-pattern. In Java we use Exceptions.
try {
return wsObject.getFoo().getBar().getBaz().getInt();
} catch (NullPointerException ignored) {
throw new MyOperationFailedException();
}
EDIT:
According to the discussion in comments let me add something to my previous thoughts. In this code there are two possibilities. One is that you accept null and the other one is, that it is an error.
If it's an error and it occurs, You can debug your code using other structures for debugging purposes when breakpoints aren't enough.
If it's acceptable, you don't care about where this null appeared. If you do, you definitely shouldn't chain those requests.
The method you have is lengthy, but very readable. If I were a new developer coming to your code base I could see what you were doing fairly quickly. Most of the other answers (including catching the exception) don't seem to be making things more readable and some are making it less readable in my opinion.
Given that you likely don't have control over the generated source and assuming you truly just need to access a few deeply nested fields here and there then I would recommend wrapping each deeply nested access with a method.
private int getFooBarBazInt() {
if (wsObject.getFoo() == null) return -1;
if (wsObject.getFoo().getBar() == null) return -1;
if (wsObject.getFoo().getBar().getBaz() == null) return -1;
return wsObject.getFoo().getBar().getBaz().getInt();
}
If you find yourself writing a lot of these methods or if you find yourself tempted to make these public static methods then I would create a separate object model, nested how you would like, with only the fields you care about, and convert from the web services object model to your object model.
When you are communicating with a remote web service it is very typical to have a "remote domain" and an "application domain" and switch between the two. The remote domain is often limited by the web protocol (for example, you can't send helper methods back and forth in a pure RESTful service and deeply nested object models are common to avoid multiple API calls) and so not ideal for direct use in your client.
For example:
public static class MyFoo {
private int barBazInt;
public MyFoo(Foo foo) {
this.barBazInt = parseBarBazInt();
}
public int getBarBazInt() {
return barBazInt;
}
private int parseFooBarBazInt(Foo foo) {
if (foo() == null) return -1;
if (foo().getBar() == null) return -1;
if (foo().getBar().getBaz() == null) return -1;
return foo().getBar().getBaz().getInt();
}
}
return wsObject.getFooBarBazInt();
by applying the the Law of Demeter,
class WsObject
{
FooObject foo;
..
Integer getFooBarBazInt()
{
if(foo != null) return foo.getBarBazInt();
else return null;
}
}
class FooObject
{
BarObject bar;
..
Integer getBarBazInt()
{
if(bar != null) return bar.getBazInt();
else return null;
}
}
class BarObject
{
BazObject baz;
..
Integer getBazInt()
{
if(baz != null) return baz.getInt();
else return null;
}
}
class BazObject
{
Integer myInt;
..
Integer getInt()
{
return myInt;
}
}
Giving answer which seems different from all others.
I recommend you to check for NULL in ifs.
Reason :
We should not leave a single chance for our program to be crashed.
NullPointer is generated by system. The behaviour of System
generated exceptions can not be predicted. You should not leave your
program in the hands of System when you already have a way of handling
it by your own. And put the Exception handling mechanism for the extra safety.!!
For making your code easy to read try this for checking the conditions :
if (wsObject.getFoo() == null || wsObject.getFoo().getBar() == null || wsObject.getFoo().getBar().getBaz() == null)
return -1;
else
return wsObject.getFoo().getBar().getBaz().getInt();
EDIT :
Here you need to store these values wsObject.getFoo(),
wsObject.getFoo().getBar(), wsObject.getFoo().getBar().getBaz() in
some variables. I am not doing it because i don't know the return
types of that functions.
Any suggestions will be appreciated..!!
I wrote a class called Snag which lets you define a path to navigate through a tree of objects. Here is an example of its use:
Snag<Car, String> ENGINE_NAME = Snag.createForAndReturn(Car.class, String.class).toGet("engine.name").andReturnNullIfMissing();
Meaning that the instance ENGINE_NAME would effectively call Car?.getEngine()?.getName() on the instance passed to it, and return null if any reference returned null:
final String name = ENGINE_NAME.get(firstCar);
It's not published on Maven but if anyone finds this useful it's here (with no warranty of course!)
It's a bit basic but it seems to do the job. Obviously it's more obsolete with more recent versions of Java and other JVM languages that support safe navigation or Optional.

Refactoring an arrow head anti-pattern

I have some data that I'm querying in a single method.
It's gotten to the point where it's become the arrowhead anti-pattern.
It looks something like this:
void queryData()
{
int masterIndex = getMasterIndex();
if (masterIndex != -1)
{
byte[] pageData = getMasterPage(masterIndex);
if (pageData) != null)
{
Item1 i1 = getItem1(pageData);
Item2 i2 = getItem2(pageData);
if (i1 != null && i2 != null)
{
showResults(i1, i2);
}
}
}
}
Imagine the above but larger. More if statements and each method that is called has a decent amount of logic in it.
Now what I can do is refactor the above method so all if statements are positive and early return if true.
I feel it would be cleaner to break each query and validity check into their own class though.
Each action would inherit/implement an interface like the following:
public interface Action
{
public void run();
public boolean wasSuccessful();
}
I would create a list of the actions required and run through them one at a time.
This way it is obvious to see what logic belongs with each action.
Is this over architected? Is the above an existing pattern I don't know of yet?
Thanks in advance.
I would start off by abusing the "Extract Method" function of your IDE (if it has one) and pull out each logic branch into its own method. That way you make the code a lot more readable.
You'll probably want to start off writing a unit test first to make sure the result of your refactoring doesn't break or change the business logic of the code itself. Once you have refactored into smaller methods and are confident that the code still works as originally intended, you can then look at whether you can create classes and extract the code into those.
I wouldn't say that creating classes to have your queries and validity checks would be overengineered, as long as it makes sense and is readable. As you said, you could have a List<Action> and then loop through calling the run() method on each, then check wasSuccessful() on each and output the information as needed.
This way if you ever want to change the validation or query of a given action, you just change the class that the functionality is encapsulated in and you don't have to change your actual execution code.
Look how much cleaner it is with simply the early returns:
void queryData()
{
int masterIndex = getMasterIndex();
if (masterIndex == -1)
return;
byte[] pageData = getMasterPage(masterIndex);
if (pageData == null)
return;
Item1 i1 = getItem1(pageData);
Item2 i2 = getItem2(pageData);
if (i1 == null || i2 == null)
return;
showResults(i1, i2);
}
I think this is a better approach than creating an additional class structure.

Java Null Reference Best Practice

In java, Which of the following is the more "accepted" way of dealing with possibly null references? note that a null reference does not always indicate an error...
if (reference == null) {
//create new reference or whatever
}
else {
//do stuff here
}
or
try {
//do stuff here
}
catch (NullPointerException e) {
//create new reference or whatever
}
The answers already given are excellent (don't use exceptions for control flow; exceptions are expensive to throw and handle). There's one other important reason specifically not to catch NullPointerException.
Consider a code block that does the following:
try {
reference.someMethod();
// Some other code
}
catch (NullPointerException e) {
// 'reference' was null, right? Not so fast...
}
This might seem like a safe way to handle nullity of reference ...but what if reference was non-null and someMethod() raised NPE? Or what if there was a NPE raised elsewhere in the try block? Catching NPE is a surefire way to prevent bugs from being found and fixed.
Catching exceptions is relatively expensive. It's usually better to detect the condition rather than react to it.
Of course this one
if (reference == null) {
//create new reference or whatever
}
else {
//do stuff here
}
we shouldn't rely on exception for decision making, that aren't given for that purpose at all, also they are expensive.
Well If you aren't making decision and just verifying for initialized variable then
if (reference == null) {
//create new reference or whatever
}
//use this variable now safely
I have seen some auto code generator wraps up this thing in accessors/getter method.
I think in general an exception should be reserved for exceptional circumstances - if a null reference is sometimes expected, you should check for it and handle it explicitly.
From the answers its clear that catching an exception is not good. :)
Exceptions are definitely not free of cost. This might help you to understand it in depth. .
I would also like to mention an another practice while comparing your object with a known value.
This is the traditional way to do the job: (check whether the object is null or not and then compare)
Object obj = ??? //We dont know whether its null or not.
if(obj!=null && obj.equals(Constants.SOME_CONSTANT)){
//your logic
}
but in this way, you dont have to bother about your object:
Object obj = ???
if(Constants.SOME_CONSTANT.equals(obj)){ //this will never throw
//nullpointer as constant can not be null.
}
The first one, throwing exceptions is a costly operation.
The first form:
if (reference == null)
{
//create new reference or whatever
}
else
{
//do stuff here
}
You should not use exceptions for control flow.
Exceptions are for handling exceptional circumstances that would not normally occur during normal operating conditions.
You should use exception catching where you do not expect there to be an error. If something can be null, then you should check for that.
maybe the try catch approach will start making sense in this situation when we can start doing
try {
//do stuff here
}
catch (NullPointerException e) {
//create new reference or whatever
retry;
}
This is related to your style of development, if you are developing code using "safe" style you have to use
if(null == myInstance){
// some code
}else{
// some code
}
but if you do not use this style at least you should catch exception, but in this case it NullPointerException and I think preferably to check input parameters to null and not wait to throwing exception.
Since you asked for Best Practices, I want to point out that Martin Fowler suggests to introduce a subclass for null references as best practice.
public class NullCustomer extends Customer {}
Thus, you avoiding the hassle of dealing with NullPointerException's, which are unchecked. Methods which might return a Customer value of null, would then instead return a NullCustomer instead of null.
Your check would look like:
final Customer c = findCustomerById( id );
if ( c instanceof NullCustomer ) {
// customer not found, do something ...
} else {
// normal customer treatment
printCustomer( c );
}
In my opinion, it is permissible in some cases to catch a NullPointerException to avoid complex checks for null references and enhance code readability, e.g.
private void printCustomer( final Customer c ) {
try {
System.out.println( "Customer " + c.getSurname() + " " + c.getName() + "living in " + c.getAddress().getCity() + ", " + c.getAddress().getStreet() );
} catch ( NullPointerException ex ) {
System.err.println( "Unable to print out customer information.", ex );
}
An argument against it is that by checking for individual members being null, you can write a more detailed error message, but that is often not necessary.

What is the proper way to handle a NumberFormatException when it is expected?

I'm running into this situation where I need to parse a String into an int and I don't know what to do with the NumberFormatException. The compiler doesn't complain when I don't catch it, but I just want to make sure that I'm handling this situation properly.
private int getCurrentPieceAsInt() {
int i = 0;
try {
i = Integer.parseInt(this.getCurrentPiece());
} catch (NumberFormatException e) {
i = 0;
}
return i;
}
I want to just simplify my code like this. The compiler doesn't have a problem with it, but the thread dies on the NumberFormatException.
private int getCurrentPieceAsInt() {
int i = 0;
i = Integer.parseInt(this.getCurrentPiece());
return i;
}
Google CodePro wants me to log the exception in some way, and I agree that this is best practice.
private int getCurrentPieceAsInt() {
int i = 0;
try {
i = Integer.parseInt(this.getCurrentPiece());
} catch (NumberFormatException e) {
i = 0;
e.printStackTrace();
}
return i;
}
I want this method to return 0 when the current piece is not a number or cannot be parsed. When I don't catch the NumberFormatException explicitly, does it not assign the variable i? Or is there some default value that Integer.parseInt() returns?
General style says that if I catch an exception, I should log it somewhere. I don't want to log it. It's normal operation for this exception to be thrown sometimes, which also doesn't sit well with me. I cannot find a function, however, which will tell me if Integer.parseInt() will throw an exception. So my only course of action seems to be to just call it and catch the exception.
The javadoc for parseInt doesn't help much.
Here are the specific questions I'd like to know:
Is there a method that I can call that will tell me if Integer.parseInt() will throw a NumberFormatException before calling it? Then I would have no problem logging this, since it should never happen.
If I simply do not catch the exception, will the valiable not get assigned? Then I will simply initialize it to the value that I want when it's not a number and not catch the exception.
Is there a way to mark the exception somehow explicitly that I don't care about it? I'm thinking this would be something similar to AWTEvent.consume(). If so, then I will do this so that Google CodePro doesn't see this as "unlogged".
Is there a method that I can call that will tell me if Integer.parseInt() will throw a NumberFormatException before calling it? Then I would have no problem logging this, since it should never happen.
Sadly, no. At least not in the core Java API. It's easy to write one, however - just modify the code below.
If I simply do not catch the exception, will the valiable not get assigned? Then I will simply initialize it to the value that I want when it's not a number and not catch the exception.
If you do not catch the exception then the stack will unwind until it hits a catch block that will handle it, or it will unwind completely and halt the thread. The variable will, in fact, not be assigned but this is not exactly what you want.
Is there a way to mark the exception somehow explicitly that I don't care about it? I'm thinking this would be something similar to AWTEvent.consume(). If so, then I will do this so that Google CodePro doesn't see this as "unlogged".
There may be a way to tell CodePro to ignore this particular warning. Certainly with tools like FindBugs and Checkstyle you can turn off warnings in specific locations. (EDIT: #Andy has pointed out how to do this.)
I suspect what you want is something like the Commons lang package mentioned by #daveb. It's pretty easy to write such a function:
int parseWithDefault(String s, int def) {
try {
return Integer.parseInt(s);
}
catch (NumberFormatException e) {
// It's OK to ignore "e" here because returning a default value is the documented behaviour on invalid input.
return def;
}
}
There is NumberUtils.toInt(String, int) in commons lang which will do exactly what you want.
NumberUtils.toInt("123", 42) ==> 123
NumberUtils.toInt("abc", 42) ==> 42
* Is there a way to mark the exception somehow explicitly that I don't care about it? I'm thinking this would be something similar to AWTEvent.consume(). If so, then I will do this so that Google CodePro doesn't see this as "unlogged".
Yes, you can locally disable a CodePro audit rule for one line of code:
http://code.google.com/javadevtools/codepro/doc/features/audit/locally_disabling_audit_rules.html
That said, it is not necessarily required to include diagnostic logging in every exception catch block. Sometimes, the best action is to take a default course. Sometime it's to interact with the user. It depends.
Create your own convenience method for now and future use:
public static int parseInt(final /*#Nullable*/ String s, final int valueIfInvalid) {
try {
if (s == null) {
return valueIfInvalid;
} else {
return Integer.parseInt(s);
}
} catch (final NumberFormatException ex) {
return valueIfInvalid;
}
}
Is there a method that I can call that will tell me if Integer.parseInt() will throw a NumberFormatException before calling it? Then I would have no problem logging this, since it should never happen.
Not that I'm aware of. Keep in mind that if there were, you likely end up parsing the value twice (once to validate and once to parse it). I understand you want to avoid the exception, but in this case, this is catching the exception is the standard idiom in Java and it doesn't provide another (at least that I know of).
If I simply do not catch the exception, will the valiable not get assigned? Then I will simply initialize it to the value that I want when it's not a number and not catch the exception.
You must catch the exception (even if it does nothing) or it will escape the block and throw up through the stack.
Is there a way to mark the exception somehow explicitly that I don't care about it? I'm thinking this would be something similar to AWTEvent.consume(). If so, then I will do this so that Google CodePro doesn't see this as "unlogged".
I don't know of any. I would use the above convenience method (I have something similar in a small collection of general utilities I have available for use on my all projects).
I wouldn't log it if its truly a normal condition that you are handling. I'm not familiiar with Google CodePro, but I would hope there is a way to suppress the warning, e.g. some sort of #SuppressWarnings("xxx") annotation/keyword.
Edit: I wanted to point out these comments in the comments below
This approach still doesn't handle the exception. It's bad form to catch an exception and do nothing with it. This is why I am looking for a better solution
.
... The exception (the situation) is being handled by returning the indicated valueIfInvalid. The "bad form" you are referring to the poor practice of blindly and unthinkingly writing empty catch blocks and never going back to truly consider and address the case. If the exception situation is considered and does the right thing for the situation (even if the right thing is to do nothing), then you've "handled" the exception.
You should catch the Exception as you are doing. It is annoying, but the best approach.
There is no Java API method that will return 0 when the string is not a valid int.
When the string is not an int, an exception will be thrown so your int variable will not be set unless you catch the exception as you are doing.
If its not clear how you should handle it from the getter, you shouldn't catch it and let the caller deal with it instead. If you know how it should be handled you should just do that. Logging it may not be required or very useful in this case.
Logging an exception is more useful if you don't know how to handle the exception and you are leaving it to the person reading the logs.
Your first code block is correct. i won't be implicitly converted to 0 when an exception occurs and you have to catch that exception. Setting i to 0 inside catch is correct; although you can simply replace i = 0; with return 0;. You cannot avoid exception handling in this case.
To clarify, you can use this:
private int getCurrentPieceAsInt() {
int i = 0;
try {
i = Integer.parseInt(this.getCurrentPiece());
} catch (NumberFormatException e) {
// log that an exception occured if it's needed
return 0;
}
return i;
}
As others have mentioned, there is not a built-in core Java API method you can call to validate an integer, but you can use the Character class to validate your input without using exception handling. For example:
package com.example.parseint;
public class ValidateIntExample {
public static boolean isInteger(String s) {
if (s == null) {
return false;
}
s = s.trim();
if (s.length() == 0) {
return false;
}
int start = 0;
if (s.charAt(0) == '-') { // handle negative numbers
if (s.length() == 1) {
return false;
}
else {
start = 1;
}
}
for (int i = start; i < s.length(); i++) {
if (! Character.isDigit(s.charAt(i))) {
return false;
}
}
return true;
}
}
In fact, parseInt itself uses Character.isDigit internally, which you can verify in the JRE source code. (Sorry, I would have included the parseInt method here, but I'm not sure if I'm allowed under the license terms.) If you're using Eclipse and you have the JRE source code attached to your project, you can right-click on the method Integer.parseInt in your code and click Open Declaration.

Extract Method with continue

We're refactoring a long method; it contains a long for loop with many continue statements. I'd like to just use the Extract Method refactoring, but Eclipse's automated one doesn't know how to handle the conditional branching. I don't, either.
Our current strategy is to introduce a keepGoing flag (an instance variable since we're going to want to extract method), set it to false at the top of the loop, and replace every continue with setting the flag to true, then wrapping all the following stuff (at different nesting levels) inside an if (keepGoing) clause. Then perform the various extractions, then replace the keepGoing assignments with early returns from the extracted methods, then get rid of the flag.
Is there a better way?
Update: In response to comments - I can't share the code, but here's an anonymized excerpt:
private static void foo(C1 a, C2 b, C3 c, List<C2> list, boolean flag1) throws Exception {
for (int i = 0; i < 1; i++) {
C4 d = null;
Integer e = null;
boolean flag2 = false;
boolean flag3 = findFlag3(a, c);
blahblahblah();
if (e == null) {
if (flag1) {
if (test1(c)) {
if (test2(a, c)) {
Integer f = getF1(b, c);
if (f != null)
e = getE1(a, f);
if (e == null) {
if (d == null) {
list.add(b);
continue;
}
e = findE(d);
}
} else {
Integer f = getF2(b, c);
if (f != null)
e = getE2(a, f);
if (e == null) {
if (d == null) {
list.add(b);
continue;
}
e = findE(d);
}
flag2 = true;
}
} else {
if (test3(a, c)) {
Integer f = getF2(b, c);
if (f != null)
e = getE2(a, f);
if (e == null) {
if (d == null) {
list.add(b);
continue;
}
e = findE(d);
}
flag2 = true;
} else {
if (d == null) {
list.add(b);
continue;
}
e = findE(d);
flag2 = true;
}
}
}
if (!flag1) {
if (d == null) {
list.add(b);
continue;
}
e = findE(d);
}
}
if (e == null) {
list.add(b);
continue;
}
List<C2> list2 = blahblahblah(b, list, flag1);
if (list2.size() != 0 && flag1) {
blahblahblah();
if (!otherTest()) {
if (yetAnotherTest()) {
list.add(b);
continue;
}
blahblahblah();
}
}
}
}
This is one of those fun ones where no single pattern will get you there.
I would work at it iteratively.
First I'd try to see if I couldn't use an early continue to remove one of those levels of ifs. It's much clearer code to check for a condition and return early (or in your case continue) than to have deeply nested ifs.
Next I think I'd take some of the inner chunks and see if they couldn't be extracted into a separate method. It looks like the first two big blocks (within the "if (test2(a, c)) {" and its else statement) are very similar. There is cut and paste logic that should be the same.
Finally after that stuff is cleared up, you can start looking at your actual problem--you need more classes. This entire statement is probably a three line polymorphic method in 3-5 sibling classes.
It's very close to throw-away and rewrite code, once you identify your actual classes, this entire method will vanish and be replaced with something so simple it hurts. Just the fact that it's a static utility method should be telling you something--you don't want one of those in this type of code.
Edit (After looking a little more):
There is so much here it would be really fun to go through. Remember that when you are done you want no code duplication--and I'm pretty sure this entire thing could be written without a single if--I think all your ifs are cases that could/should easily be handled by polymorphism.
Oh, and as an answer to your question of eclipse not wanting to do it--don't even TRY automatic refactoring with this one, just do it by hand. The stuff inside that first if() needs to be pulled out into a method because it's virtually identical to the clause in its else()!
When I do something like this, I usually create a new method, move the code from the if into the new method (leaving just a call to the new method inside the if), then run a test and make sure you didn't break anything.
then go line by line and check to ensure there is no difference between the if and its else code. If there is, compensate for it by passing the difference as a new variable to the method. After you're sure everything is identical, replace the else clause with a call. Test again. Chances are at this point a few additional optimizations will become obvious, you'll most likely lose the entire if by combining it's logic with the variable you passed to differentiate the two calls.
Just keep doing stuff like that and iterating. The trick with refactoring is to use Very Small Steps and test between each step to ensure nothing changed.
continue is basically an analogue of an early return, right?
for (...) {
doSomething(...);
}
private void doSomething(...) {
...
if (...)
return; // was "continue;"
...
if (!doSomethingElse(...))
return;
...
}
private boolean doSomethingElse(...) {
...
if (...)
return false; // was a continue from a nested operation
...
return true;
}
Now I must admit that I didn't quite follow your current strategy, so I might have just repeated what you said. If so, then my answer is that I can't think of a better way.
If I were faced with your situation I would look at using other refactoring techniques such as "replace conditional with polymorphism". That said you should always do one thing at a time, so if you first want to extract method you have two options:
Add the "keepGoing" flag
Throw an exception from the method
Of these two options, I think the keepGoing flag is better. I wouldn't stop refactoring after you extract the method. I am sure once you have a smaller method you will find a way to remove this flag and have cleaner logic.
I'm going to summarize the answers here, while accepting Bill K's answer as the most complete. But everyone had something good to offer, and I might use any of these approaches next time I'm faced with this sort of situation.
mmyers: Cut out the loop body, paste it into a new method and replace all the continues with returns. This worked very nicely, although it would have trouble if there were other control flow statements, like break and return, inside the loop.
Bill K: Tease it apart iteratively; look for duplication and eliminate it. Take advantage of polymorphic classes to replace the conditional behavior. Use Very Small Steps. Yes; this is all good advice, with broader applicability than just this specific case.
Aaron: Either use the keepGoing flag to replace the continue or throw an Exception. I didn't try this, but I think the Exception option is a very nice alternative, and one I hadn't considered.

Categories

Resources