Related
Assume I have a Java method
public X findX(...)
which tries to find an Object of type X fulfilling some conditions (given in the parameters). Often such functions cannot guarantee to find such an object. I can think of different ways to deal with this:
One could write an public boolean existsX(...) method with the same signature which should be called first. This avoids any kind of exceptions and null handling, but probably you get some duplicate logic.
One could just return null (and explain this in javadoc). The caller has to handle it.
One could throw a checked exception (which one would fit for this?).
What would you suggest?
The new Java 8 Optional class was made for this purpose.
If the object exists then you return Optional.of(x) where x is the object, if it doesn't then return Optional.empty(). You can check if an Optional has an object present by using the isPresent() method and you can get the object using get().
https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html
If you can't use Optional I would go with option 2.
In the case of 1. You'd be doing double work, first you have to check if X exists, but if it does, you're basically discarding the result, and you have to do the work again in findX. Although the result of existsX could be cached and checked first when calling findX, this would still be an extra step over just returning X.
In the case of 3. To me this comes down to usability. Sometimes you just know that findX will return a result (and if it doesn't, there is a mistake somewhere else), but with a checked exception, you would still have to write the try and (most likely empty) catch block.
So option 2 is the winner to me. It doesn't do extra work, and checking the result is optional. As long as you document the null return, there should be no problems.
Guava (potentially other libraries, too) also offers an Optional class that might be worth exploring if your project uses Guava since you seem to not use Java 8.
If you
don't/can't/won't use Java 8 and its accompanying Optional type
don't want another library dependency (like Guava) for a single class implementation
but
you want something more robust than methods that can return null for which you have to have a check in all consumers (which was the standard before Java 8)
then writing your own Optional as an util class is the easiest option.
I ran into an odd situation during a use case on a project: ESQL is calling a java method, sending it a String input parameter which the method will unmarshal, apply some logic, and then store useful info from the unmarshalled object. So, the method must either throw a JAXBException, or use a try catch in order to handle the possible exceptions.
The problem with this is, that ESQL cannot invoke a java method which includes a throws in the signature. BUT, we want any errors to fall through back to the previously calling MBNode so it can be handled appropriately there, so then trycatch is out of the picture.
It struck me that hey, is it not possible to return a type of Exception when we encounter an issue, and null if not? So I wrote a simple method doing so, and though I didn't get any warnings or errors, it seemed just wrong to me in the sense of good programming.
For example:
public Exception doStuffAndCheckForErorrs(String inString)
{
if(inString.equals(null))
{
return new Exception("Your string is null");
}
else
return null;
}
But I just get a terrible feeling about doing anything this way.
I'm open to any thoughts or different solutions to this, especially if there's a way around the ESQL signature issue.
UPDATE:
Adding reference as to why the ESQL procedure cannot call a java method with a throws clause in the signature.
Excerpt from This link under the CREATE PROCEDURE statement section:
"Any Java method that you want to invoke must have the following basic signature:
public static (< 0 - N parameters>)
where must be in the list of Java IN data types in the table in ESQL to Java data type mapping (excluding the REFERENCE type, which is not permitted as a return value), or the Java void data type. The parameter data types must also be in the ESQL to Java data type mapping table. In addition, the Java method is not allowed to have an exception throws clause in its signature."
This isn't really a question about Java, it's a question about ESQL.
ESQL is able to cope with Java exceptions being thrown through the JNI into ESQL code, you should get a BIP2917 error.
I initially though this might have been an issue with the ESQL method resolver but on IIB v9 I was able to succesfully call the following method:
public static void sayHello() throws Exception{
System.out.println("hello");
}
This makes me think that perhaps you got something else wrong with your ESQL external function/procedure definition?
The point here is you can't DECLARE an exception will be thrown; you can still throw a RuntimeException - without adding a throws clause.
So if you wrap your JAXBException into a RuntimeException, you can throw it and handle according to your requirements, without breaking either requirement. Not sure if I would do that; I would not like to return an exception-type though as it's not meant to be used as a return code.
Be extra sure that this asynch way of handling the issue won't break the ESQL library, as you'll be bypassing part of their code, possibly leaving part of it hanging.
Returning Exception is "quick and dirty". It can be very powerful and useful but this should be avoid if possible.
The invocation in ESQL are made like this for a good reason i won't explained here but you can bypass it by using RuntimeException that does not appears in the method definition.
A use case that specifies throwing an Exception sounds like it may be poorly written.
What is the business or architectural reason for throwing an Exception?
An alternative would be throw a RuntimeException or a custom subclass.
That would allow you to leave it out of the method signature.
Again, the use case seems odd.
The straightforward answer to your question is:
No, it isn't good programming to have a return type of Exception.
The mechanism is meant to happen when something goes wrong, therefore a return type of Exception means that you want to receive the consequence of something that went wrong.
I understand that you can't throw Exception, so you should handle the case with other approach.
The boolean aproach is fine when you want to check up some work: good = return true, bad= return false.
The encapsulation of values in an Object is meant when you want to grab the results of the work: good = return new YourResultObject(val1, val2, ..., valx), bad = return null.
What you can do is use return codes like C programs used to do to report about their states.
Alternatively you can also create an Enum and return the Enum, both are more flexible than the Boolean approach if you want to differentiate between different types of errors
public Enum ReturnCodes {
SUCCESS,
NULLSTRING,
...,
OTHERERROR,
}
I'm wondering if it is an accepted practice or not to avoid multiple calls on the same line with respect to possible NPEs, and if so in what circumstances. For example:
anObj.doThatWith(myObj.getThis());
vs
Object o = myObj.getThis();
anObj.doThatWith(o);
The latter is more verbose, but if there is an NPE, you immediately know what is null. However, it also requires creating a name for the variable and more import statements.
So my questions around this are:
Is this problem something worth
designing around? Is it better to go
for the first or second possibility?
Is the creation of a variable name something that would have an effect performance-wise?
Is there a proposal to change the exception
message to be able to determine what
object is null in future versions of
Java ?
Is this problem something worth designing around? Is it better to go for the first or second possibility?
IMO, no. Go for the version of the code that is most readable.
If you get an NPE that you cannot diagnose then modify the code as required. Alternatively, run it using the debugger and use breakpoints and single stepping to find out where the null pointer is coming from.
Is the creation of a variable name something that would have an effect performance-wise?
Adding an extra variable may increase the stack frame size, or may extend the time that some objects remain reachable. But both effects are unlikely to be significant.
Is there a proposal to change the exception message to be able to determine what object is null in future versions of Java ?
Not that I am aware of. Implementing such a feature would probably have significant performance downsides.
The Law of Demeter explicitly says not to do this at all.
If you are sure that getThis() cannot return a null value, the first variant is ok. You can use contract annotations in your code to check such conditions. For instance Parasoft JTest uses an annotation like #post $result != null and flags all methods without the annotation that use the return value without checking.
If the method can return null your code should always use the second variant, and check the return value. Only you can decide what to do if the return value is null, it might be ok, or you might want to log an error:
Object o = getThis();
if (null == o) {
log.error("mymethod: Could not retrieve this");
} else {
o.doThat();
}
Personally I dislike the one-liner code "design pattern", so I side by all those who say to keep your code readable. Although I saw much worse lines of code in existing projects similar to this:
someMap.put(
someObject.getSomeThing().getSomeOtherThing().getKey(),
someObject.getSomeThing().getSomeOtherThing())
I think that no one would argue that this is not the way to write maintainable code.
As for using annotations - unfortunately not all developers use the same IDE and Eclipse users would not benefit from the #Nullable and #NotNull annotations. And without the IDE integration these do not have much benefit (apart from some extra documentation). However I do recommend the assert ability. While it only helps during run-time, it does help to find most NPE causes and has no performance effect, and makes the assumptions your code makes clearer.
If it were me I would change the code to your latter version but I would also add logging (maybe print) statements with a framework like log4j so if something did go wrong I could check the log files to see what was null.
I’m from a .NET background and now dabbling in Java.
Currently, I’m having big problems designing an API defensively against faulty input. Let’s say I’ve got the following code (close enough):
public void setTokens(Node node, int newTokens) {
tokens.put(node, newTokens);
}
However, this code can fail for two reasons:
User passes a null node.
User passes an invalid node, i.e. one not contained in the graph.
In .NET, I would throw an ArgumentNullException (rather than a NullReferenceException!) or an ArgumentException respectively, passing the name of the offending argument (node) as a string argument.
Java doesn’t seem to have equivalent exceptions. I realize that I could be more specific and just throw whatever exception comes closest to describing the situation, or even writing my own exception class for the specific situation.
Is this the best practice? Or are there general-purpose classes similar to ArgumentException in .NET?
Does it even make sense to check against null in this case? The code will fail anyway and the exception’s stack trace will contain the above method call. Checking against null seems redundant and excessive. Granted, the stack trace will be slightly cleaner (since its target is the above method, rather than an internal check in the HashMap implementation of the JRE). But this must be offset against the cost of an additional if statement, which, furthermore, should never occur anyway – after all, passing null to the above method isn’t an expected situation, it’s a rather stupid bug. Expecting it is downright paranoid – and it will fail with the same exception even if I don’t check for it.
[As has been pointed out in the comments, HashMap.put actually allows null values for the key. So a check against null wouldn’t necessarily be redundant here.]
The standard Java exception is IllegalArgumentException. Some will throw NullPointerException if the argument is null, but for me NPE has that "someone screwed up" connotation, and you don't want clients of your API to think you don't know what you're doing.
For public APIs, check the arguments and fail early and cleanly. The time/cost barely matters.
Different groups have different standards.
Firstly, I assume you know the difference between RuntimeExceptions (unchecked) and normal Exceptions (checked), if not then see this question and the answers. If you write your own exception you can force it to be caught, whereas both NullPointerException and IllegalArgumentException are RuntimeExceptions which are frowned on in some circles.
Secondly, as with you, groups I've worked with but don't actively use asserts, but if your team (or consumer of the API) has decided it will use asserts, then assert sounds like precisely the correct mechanism.
If I was you I would use NullPointerException. The reason for this is precedent. Take an example Java API from Sun, for example java.util.TreeSet. This uses NPEs for precisely this sort of situation, and while it does look like your code just used a null, it is entirely appropriate.
As others have said IllegalArgumentException is an option, but I think NullPointerException is more communicative.
If this API is designed to be used by outside companies/teams I would stick with NullPointerException, but make sure it is declared in the javadoc. If it is for internal use then you might decide that adding your own Exception heirarchy is worthwhile, but personally I find that APIs which add huge exception heirarchies, which are only going to be printStackTrace()d or logged are just a waste of effort.
At the end of the day the main thing is that your code communicates clearly. A local exception heirarchy is like local jargon - it adds information for insiders but can baffle outsiders.
As regards checking against null I would argue it does make sense. Firstly, it allows you to add a message about what was null (ie node or tokens) when you construct the exception which would be helpful. Secondly, in future you might use a Map implementation which allows null, and then you would lose the error check. The cost is almost nothing, so unless a profiler says it is an inner loop problem I wouldn't worry about it.
In Java you would normally throw an IllegalArgumentException
If you want a guide about how to write good Java code, I can highly recommend the book Effective Java by Joshua Bloch.
It sounds like this might be an appropriate use for an assert:
public void setTokens(Node node, int newTokens) {
assert node != null;
tokens.put(node, newTokens);
}
Your approach depends entirely on what contract your function offers to callers - is it a precondition that node is not null?
If it is then you should throw an exception if node is null, since it is a contract violation. If it isnt then your function should silently handle the null Node and respond appropriately.
I think a lot depends on the contract of the method and how well the caller is known.
At some point in the process the caller could take action to validate the node before calling your method. If you know the caller and know that these nodes are always validated then i think it is ok to assume you'll get good data. Essentially responsibility is on the caller.
However if you are, for example, providing a third party library that is distributed then you need to validate the node for nulls, etcs...
An illegalArugementException is the java standard but is also a RunTimeException. So if you want to force the caller to handle the exception then you need to provided a check exception, probably a custom one you create.
Personally I'd like NullPointerExceptions to ONLY happen by accident, so something else must be used to indicate that an illegal argument value was passed. IllegalArgumentException is fine for this.
if (arg1 == null) {
throw new IllegalArgumentException("arg1 == null");
}
This should be sufficient to both those reading the code, but also the poor soul who gets a support call at 3 in the morning.
(and, ALWAYS provide an explanatory text for your exceptions, you will appreciate them some sad day)
like the other : java.lang.IllegalArgumentException.
About checking null Node, what about checking bad input at the Node creation ?
I don't have to please anybody, so what I do now as canonical code is
void method(String s)
if((s != null) && (s instanceof String) && (s.length() > 0x0000))
{
which gets me a lot of sleep.
Others will disagree.
If I get a NullPointerException in a call like this:
someObject.getSomething().getSomethingElse().
getAnotherThing().getYetAnotherObject().getValue();
I get a rather useless exception text like:
Exception in thread "main" java.lang.NullPointerException
at package.SomeClass.someMethod(SomeClass.java:12)
I find it rather hard to find out which call actually returned null, often finding myself refactoring the code to something like this:
Foo ret1 = someObject.getSomething();
Bar ret2 = ret1.getSomethingElse();
Baz ret3 = ret2.getAnotherThing();
Bam ret4 = ret3.getYetAnotherOject();
int ret5 = ret4.getValue();
and then waiting for a more descriptive NullPointerException that tells me which line to look for.
Some of you might argue that concatenating getters is bad style and should be avoided anyway, but my Question is: Can I find the bug without changing the code?
Hint: I'm using eclipse and I know what a debugger is, but I can't figuer out how to apply it to the problem.
My conclusion on the answers:
Some answers told me that I should not chain getters one after another, some answers showed my how to debug my code if I disobeyed that advice.
I've accepted an answer that taught me exactly when to chain getters:
If they cannot return null, chain them as long as you like. No need for checking != null, no need to worry about NullPointerExceptions (be warned that chaining still violates the Law of Demeter, but I can live with that)
If they may return null, don't ever, never ever chain them, and perform a check for null values on each one that may return null
This makes any good advice on actual debugging useless.
NPE is the most useless Exception in Java, period. It seems to be always lazily implemented and never tells exactly what caused it, even as simple as "class x.y.Z is null" would help a lot in debugging such cases.
Anyway, the only good way I've found to find the NPE thrower in these cases is the following kind of refactoring:
someObject.getSomething()
.getSomethingElse()
.getAnotherThing()
.getYetAnotherObject()
.getValue();
There you have it, now NPE points to correct line and thus correct method which threw the actual NPE. Not as elegant solution as I'd want it to be, but it works.
The answer depends on how you view (the contract of) your getters. If they may return null you should really check the return value each time. If the getter should not return null, the getter should contain a check and throw an exception (IllegalStateException?) instead of returning null, that you promised never to return. The stacktrace will point you to the exact getter. You could even put the unexpected state your getter found in the exception message.
In IntelliJ IDEA you can set exceptionbreakpoints. Those breakpoints fire whenever a specified exception is thrown (you can scope this to a package or a class).
That way it should be easy to find the source of your NPE.
I would assume, that you can do something similar in netbeans or eclipse.
EDIT: Here is an explanation on how to add an exceptionbreakpoint in eclipse
If you find yourself often writing:
a.getB().getC().getD().getE();
this is probably a code smell and should be avoided. You can refactor, for example, into a.getE() which calls b.getE() which calls c.getE() which calls d.getE(). (This example may not make sense for your particular use case, but it's one pattern for fixing this code smell.)
See also the Law of Demeter, which says:
Your method can call other methods in its class directly
Your method can call methods on its own fields directly (but not on the fields' fields)
When your method takes parameters, your method can call methods on those parameters directly.
When your method creates local objects, that method can call methods on the local objects.
Therefore, one should not have a chain of messages, e.g. a.getB().getC().doSomething(). Following this "law" has many more benefits apart from making NullPointerExceptions easier to debug.
I generally do not chain getters like this where there is more than one nullable getter.
If you're running inside your ide you can just set a breakpoint and use the "evaluate expression" functionality of your ide on each element successively.
But you're going to be scratching your head the moment you get this error message from your production server logs. So best keep max one nullable item per line.
Meanwhile we can dream of groovy's safe navigation operator
Early failure is also an option.
Anywhere in your code that a null value can be returned, consider introducing a check for a null return value.
public Foo getSomething()
{
Foo result;
...
if (result == null) {
throw new IllegalStateException("Something is missing");
}
return result;
}
Here's how to find the bug, using Eclipse.
First, set a breakpoint on the line:
someObject.getSomething().getSomethingElse().
getAnotherThing().getYetAnotherObject().getValue();
Run the program in debug mode, allow the debugger to switch over to its perspective when the line is hit.
Now, highlight "someObject" and press CTRL+SHIFT+I (or right click and say "inspect").
Is it null? You've found your NPE. Is it non-null?
Then highlight someObject.getSomething() (including the parenthesis) and inspect it.
Is it null? Etc. Continue down the chain to figure out where your NPE is occurring, without having to change your code.
You may want to refer to this question about avoiding != null.
Basically, if null is a valid response, you have to check for it. If not, assert it (if you can). But whatever you do, try and minimize the cases where null is a valid response for this amongst other reasons.
If you're having to get to the point where you're splitting up the line or doing elaborate debugging to spot the problem, then that's generally God's way of telling you that your code isn't checking for the null early enough.
If you have a method or constructor that takes an object parameter and the object/method in question cannot sensibly deal with that parameter being null, then just check and throw a NullPointerException there and then.
I've seen people invent "coding style" rules to try and get round this problem such as "you're not allowed more than one dot on a line". But this just encourages programming that spots the bug in the wrong place.
Chained expressions like that are a pain to debug for NullPointerExceptions (and most other problems that can occur) so I would advise you to try and avoid it. You have probably heard that enough though and like a previous poster mentioned you can add break points on the actual NullPointerException to see where it occurred.
In eclipse (and most IDEs) you can also use watch expressions to evaluate code running in the debugger. You do this bu selecting the code and use the contet menu to add a new watch.
If you are in control of the method that returns null you could also consider the Null Object pattern if null is a valid value to return.
Place each getter on its own line and debug. Step over (F6) each method to find which call returns null