How to handle possible NULL correctly? [closed] - java

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
While reading several different API codes I discovered that they handle possible nulls on different ways. And here at stackoverflow I have read several recommendations like no need for explicit checking or check and throw some meaning full exception...etc.
Say the method is something like this:
public void runThis(SomeObject obj){
## null handling code comes here ##
obj.doSomething() <- possible NPE
}
The most common solutions I have seen:
1.Throwing explicit NPE
if(obj==null){
throw new NullPointerException();
}
2.Throwing custom exception
if(obj==null){
throw new CustomException("Null not allowed here");
}
3.Using Assert (have seen it only once)
assert obj!=null
4.Do nothing and java will throw it when invoking doSomething()
//
Is there some general - best all over the place - solution to this?

Is there some general - best all over the place - solution to this?
No.
This is because null doesn't have a commonly agreed meaning. It might be a result of a bug, indicate missing data, or represent a default value.
Here are some tips:
requireNonNull is better than writting if (x == null) everywhere.
Optional
Failing fast is good, so do throw an exception if you encounter an unexpected null. NullPointerException is fine, IllegalArgumentException is also ok. Bike sheds should be painted black.
Don't use asserts - this is a dead language feature.
Don't mask null values (it's like ignoring errors).
If you are looking for a solution that solves the null problem once and for all, I would like to take this opportunity to promote Kotlin - a programming language which does a good job of clearing up this mess. The null problem basically dissapears in Kotlin, yet at the same time it is easy to migrate from Java.

It depends on where you got obj, and what you plan to do with it.
Exceptions should be used to check for invalid values in user input, and invalid values passed to public/protected methods.
This is to ensure that your method can safely execute, and to provide a helpful message if it can't. Use custom exceptions for this purpose.
Assertions should be used to check things that you believe should always be true. They are a tool to find bugs in your code, seeing as they're usually disabled in release builds.
The most common use of assertions is in tests.

Related

Which Exception to throw when 1 parameter has an illegal value based on a 2nd parameter [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I have a method that takes 2 boolean parameters. If the first parameter is true, the 2nd parameter can not also be true.
If they are both true I want to throw an Exception, but I am not sure which exception is the most accurate.
Example:
public void addEvent(boolean hadPositiveResult, boolean needsFurtherStudy) {
if (hadPositiveResult && needsFurtherStudy)
throw new Exception("Can not need further study if the event had a positive result"); //this should be a more specific exception
//rest of method code omitted...
}
Would IllegalArgumentException or IllegalStateException make sense? Is there a better one that describes it better?
Consider not doing it that way. Don't get into the "I need a bunch of flags on my methods" game.
You see, good interfaces make it hard for your client code to do the wrong thing! In your case, one "gets it wrong" by simply passing (true, true). That sounds awfully easy to get wrong. Especially as your method name doesn't indicate at all that addEvent(true, true) will throw up at runtime. Honestly: that is in no way a robust design!
One potential solution: use an enum instead of a boolean. That enum contains only constants for valid cases. But honestly, having something like
enum AdderConditions {
NONE, NEEDS_POSITIVE_RESULT, NEEDS_FURTHER_STUDY };
isn't too appealing either.
In order to really "resolve" this, it would be necessary to understand your requirements in detail; and probably design a completely different solution; but that is something beyond the scope of this site.
So, my personal recommendation: find somebody around you who is really experienced in doing good OO designs; show him your problem and ask how he would restructure your whole flow to avoid getting into the "setting flags" business completely! I guarantee you: it will be worth it.
Sooner or later, you might have "other" flags somewhere, and then you end up with client code doing "true, false, true", and so on; and nobody understands what that is doing, or why the one combination works; and the other gives you exceptions.
From https://docs.oracle.com/javase/7/docs/api/java/lang/IllegalArgumentException.html
Thrown to indicate that a method has been passed an illegal or
inappropriate argument.
So yes, it sounds like throwing an IllegalArgumentException would be appropriate. Additionally you can add a message to the exception to inform the caller of the error, e.g.
if (param1 && param2) {
throw new IllegalArgumentException("Both parameters cannot be true");
}
For this you can throw IllegalArgumentException, but inside message you can say what was wrong with the parameters, for example:
throw new IllegalArgumentException("second parameter....");
Then you can get the message in the catch clause and check what was wrong.

Applicability of two or more exception types at the same time [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
Suppose I design a method that computes the arcsin function. Of course, only numbers in the closed interval [-1,1] are acceptable as arguments to the function.
If, however, a number outside that interval is passed, the method throws an exception. My question is, are IllegalArgumentException and ArithmeticException both equally applicable? If yes, cite some more examples of cases where two or more exception types are equally applicable. If not, why?
In Java, it's possible to raise one type of exception at a time.
It's possible to nest exceptions (by wrapping one exception around another -- see the cause argument as part of the base Exception() constructor)
In the arcsin case, the argument thrown would depend on how the function contract is defined. It could be argued that either exception is applicable, but given that the valid range for the input arguments is well defined, these can be made explicit as part of the contract, and invalid arguments rejected via the use of an IllegalArgumentException.
The use of an IllegalArgumentException is :
Thrown to indicate that a method has been passed an illegal or
inappropriate argument.
Given that it's possible to prevent doing any arithmetic knowing the range of acceptable values in advance, this seems to be the right choice of exception to throw.
This is really a factor of your design in deciding how something should work. Another option is to throw a custom checked exception, I think as long as your consistent within your package/API, and follow your established coding standards if you have any, you'll be fine. I think either is a valid choice among those two, I would just make a design decision and document it, so that it is an established decision for future development. All that said, I would probably pick IllegalArgumentException because its an earlier detection of the problem.
IllegalArgumentException seems more valid of the two. It tells me that I've done something wrong (I.E. passed invalid arguments) whereas ArithmeticException implies that the application was incapable of performing the arithmetic but gives no clues as to why.

Is this an overuse of Java asserts? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I'm trying to get to grips with the use of the assert keyword in Java. As I understand it, the correct case is for verifying things that should always be true.
I'm worried that I'm overusing asserts, however.
Here's a sample:
private BodyParams() {
assert revokedDoc != null : "revokedDoc must not be null";
assert revokedDoc.getStatus() == DocumentStatus.Revoked : "document is not revoked";
assert !isBlank(revokedDoc.getDocType()) : "docType should not be blank";
assert revokedDoc.getIssuedDate() != null : "doc should have issue date";
assert revokedDoc.getSendingOrg() != null
&& !isBlank(revokedDoc.getSendingOrg().getName())
: "sending ord should exists and name should ne populated";
if (registeredUser) {
assert revokedDoc.getOwner() != null
&& !isBlank(revokedDoc.getOwner().getFirstName())
: "owner should exists and first name should be populated";
this.ownerFirstName = revokedDoc.getOwner().getFirstName();
this.docUrl = Application.PUBLIC_HOSTNAME
+ controllers.routes.DocumentActions.viewDocument(
revokedDoc.getId()
).url();
} else {
this.ownerFirstName = null;
this.docUrl = null;
}
if (revokedDoc.getStatus() == DocumentStatus.Available) {
assert !isBlank(revokedDoc.getFriendlyName())
: "friendly name should not be blank for picked-up docs";
this.friendlyName = revokedDoc.getFriendlyName();
} else {
this.friendlyName = null;
}
this.docType = revokedDoc.getDocType();
this.issueDate = revokedDoc.getIssuedDate();
this.issuerName = revokedDoc.getSendingOrg().getName();
}
In this example, it is assumed that the revokedDoc field came from the database, and correct validation was performed when it was inserted. These asserts test that assumption. Is this overkill?
edit: I should mention that this is only for development code. Assertions will not be enabled in production. I'm using the assertions to ensure that data that will be known good data from a trusted source in production behaves itself in development
It does not look right. To simplify there are two broad categories of problems that can arise and require checking the validity of a variable:
Your method receives or uses an argument that could possibly not be what you expect and your method should have appropriate argument checking and throw an IllegalArgumentException or NullPointerException or whatever if required. Example: the client code has passed in a null argument and you have no control over that code
Your method uses some of the class internals and you should have appropriate unit tests to make sure that those internals are always consistent and that your methods can use them without additional checks.
In your case, the method that creates the revokeDoc object should make sure it is in a valid state after creation and take appropriate action otherwise, for example throw an exception and roll back any changes. That way your BodyParams method can just use the object without all those asserts which clutter your code at the wrong time: if revokeDoc is not consistent it is probably too late to do something about it and should have been detected earlier.
Related post: Exception Vs Assertion
Assert is really useful to perform that should always be true inside an library or a module. It is intented to verify invariants ( control flow, internal, etc.) in your code, and it is a bad idea to use it to enforce correct use of your code (you have exceptions for that).
As a consequence, your public interface should never be based on assert : when you have a public method and you want to check input parameter, it is generally better to throw an IllegalArgumentException.
Here are some good documentation about asserts.
In your example, I think you should use exceptions instead of asserts. It's not a bad idea to perform some validity checks on data coming from a database (even if it has been validated on input) but assertion might be disabled in production code and you have to think on how you should handle such malformed content.
This could be an opinionated question. However, I'd go with the following things to decide:
Is this method exposed to outside world (via an interface, JAR file, user input field or anywhere where you could get inputs from a source that is not in your control) - then I should have a valid actual check which would result in an exception.
Am i relying on assertion for my correct execution of the code? If so, I shouldn't. At runtime, assertions are meant to be disabled.
Is this assertion always true? and if yes, am I going to use it on the off case for just debugging - then yes, use an assertion in place of a code comment. When something goes bad, enable the assertions and figure out what's wrong.
You need to consider two scenarios: development code and production code.
Since Java's assert statement is disabled by default (and adds only little overhead by checking a global static flag which is enabled by passing -ea to the VM), I would not consider this overhead since it helps you detect issues early during your development phase (assumed that you have enabled assertions in your development environment).
On the other hand, you say "... Correct validation was performed when it was inserted ..." - so, how do you know that the value has not been changed in the database meanwhile? If security matters for your system (I am just assuming it does), one basic pattern is that you must not trust anything which you get from the outside. Means, validate values you read from the database - but, in that case, assert is not the proper tool. Use normal validation code and exceptions for that.
The best practice, acording to OO metology is to check the params you receive. And create regulars checks for others. Should in your case you should get something like this:
private BodyParams(revokedDoc)
[...]
asserts of the params
if(isBlank(revokedDoc.....)
All the assets looks good, and is the way to make sure the method has everything to work. But they should be to make an aide of what's going on wrong, not to make your program work.

Best practice to return object in java [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
lets say we have a class called Intersection, with a findIntersect(line1, line2) method. It returns an object called point, with 2 fields the x and y coordinates. Now, if the input are 2 parallel lines, what is the best way to communicate that no result was obtained with the user? Though example is specific to lines, the question is generic - assuming a method returns value object, what to return if conditions don't match? Some options are:
Return null (issue: read in many places that null return value should be avoided if possible)
Have a method in object which determines if object is valid, similar to hasNext() in Iterator?
Throw an Exception?
Please let me know best approach.
Whatever you do, document it. As a caller of the function, I would expect the exact behavior, particularly for edge cases, to be clearly described in the method's JavaDoc.
In this particular case, I would probably return an Optional<Point>. Optional is quite nice because it very clearly communicates that a value might not be present. A sane API would never – never – return null if its declared return type is Optional.
More reading: Using and avoiding null and Avoiding != null statements
One should be very careful about returning nulls. Your API users will have to bloat their code with null checks.
A good solution, having an object decide if its in a valid state or not. If not it defaults to a pre-defined state.
A possible solution, if it makes sense in your API's case. For example: Is the user allowed to pass 2 parallel lines?
I suggest you make a condition that will prevent the program to proceed to that method if the inputs are invalid then, notify the user. By that, you don't have to adjust the object point.
Your second option seems ideal...
It is true you do not want to return null if some conditions aren't met - null doesn't mean "does not exist", it basically implies an escape sequence.
Exceptions typically are only thrown when internal computations are preformed (attempting to read a file that doesn't exist, formats of particular variables, etc.) Throwing an exception alerts the user something illegal was performed...not finding an intersection doesn't mean something illegal was found, but rather, it returns false.
It would be much 'cleaner' to call a boolean function to first test if a particular intersection exists, if so, then call your next function to find it.
Another option would be an else statement, after all iterations of findIntersect() runs...if intersection found, return it, else return some other object indicative of no intersection (ex. -1,-1)
Hope this helps.

What is the best built-in JRE Exception to throw to indicate a failed "sanity check"? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
When performing "sanity checks" at runtime, what is the best built-in Exception to throw to indicate a logic error? InternalError is tempting, but as an Error my understanding is that it should only be use to indicate problems in the JVM itself, not application logic errors. Right now I tend to throw RuntimeExceptions, but I find that distasteful because the type is so general. Is there a more specific type I should be using?
I'm avoiding using assert for these checks because they should still be performed in production. For this reason, "you should be using assert" is not The Right Answer.
I apologize for the subjective nature of this question, but I'm hoping there are some well-known best practices that I'm just not aware of.
EDIT: Here's a good example of what I'm talking about, although certainly there are other good examples and the idea is more general:
public static void foobar(ModelObject o) {
switch(o.getEnumProperty()) {
case ENUMVALUE1:
// Handle...
break;
case ENUMVALUE2:
// Handle...
break;
default:
// In theory, this should never be reached. The code should handle any
// enum value it's Java-legal for the code to pass. But, if a new
// enum value is added and this code is not updated, this WILL be
// reached. This is not an IllegalArgumentException because the caller
// passed a valid value -- remember, we SHOULD handle any enum value
// here -- but the code has not been updated. For this reason, it's an
// "internal error" of sorts. However, there's no good "my program's
// logic is broken" Exception that I know of built into the JRE. It is
// this Exception that I'm looking for in this question.
//
// Hopefully this clarifies the question somewhat.
throw new RuntimeException("Unhandled: "+o.getType());
}
}
I suppose a more specific way to phrase this question would be "What kind of Exception should I throw if there is code that should never be reached, but GETS reached, in a production environment?" This is not precisely the right question, but all "sanity checks" can be "spelled" in terms of code that should never be reached, so it's close enough.
Java is object oriented.
Throw a SanityException or a FailedSanityCheckException.
In other words, create your own class that extends Exception.
Maybe MyCompanyException would be more appropriate than SanityException ;)
If you want it to be an unchecked runtime exception, extend RuntimeException:
class SanityException extends RuntimeException {
public SanityException(String msg) {
super(msg);
}
}
It's very easy and very powerful.
Your logic can catch and handle only SanityExceptions, which is good.
I know your question asks for a built-in Exception... But if you find the built-in options distasteful because they're not specific enough, that's the exact reason to create your own (especially considering how easy it is).
Seems to me this is how Exceptions were meant to be used.
There is an AssertionError throwable exception. See http://docs.oracle.com/javase/6/docs/api/java/lang/AssertionError.html

Categories

Resources