I am trying to write less and less code and I am trying to find a way to prevent crashes.
An example what I have encountered is:
public class MyClass
{
private User user;
public MyClass()
{
// Get user from another class
// Another thread, user can be null for couple of seconds or minutes
// Asynchronous call
user = AnotherClass.getUser();
// start method
go();
}
private void go()
{
// Method 1
// Program it is crashing if user is null
if (user.getId() == 155)
{
// TO DO
}
else
{
System.out.println("User is NOT 155 !");
}
// Method 2
// Program still crashes if user is null
if (user != null && user.getId() == 155)
{
// To do
}
else
{
System.out.println("user is not 155");
}
// Method 3
// Program wont crash, but I write much more code !
if (user != null)
{
if (user.getId() == 155)
{
// To do
}
else
{
System.out.println("User is not 155 !");
}
}
else
{
System.out.println("User is not 155 !");
}
}
}
As you can see, method 3 it's working, but I am writing much more code... What should I do?
Prefer the way Short-circuit evaluation, That is method 2.
when the first argument of the AND function evaluates to false, the overall value must be false;
if (user != null && user.getId() == 155)
{
// To do
}
else
{
System.out.println("user is not 155");
}
That is the most preferable and readable code.
Your assumtions are wrong that method2 crash and method3 works. In the above code if user != null then only user.getId() == 155 executes.
Why not use a null object pattern here, so instead of setting user to be null, set it to a special 'null' case (implementation) of the User object ?
e.g.
user = AnotherClass.getUser();
if (user == null) {
user = new NullUser();
}
(ideally AnotherClass.getUser() would do the null check internally)
In this case
user.getId()
could return a special value (-1 ?) which would never equate to a valid user id. Hence your code will always look like:
if (user.getId() == 155)
The same would apply to other methods on the User object.
It's got to be something inside the block started by this statement:
if (user != null && user.getId() == 155)
That is logically identical to method 3. When the JVM sees that user is null, it should stop evaluating that.
I will say though that I encountered something like this with JVM 1.3, so if you are using a really old JVM that may be it.
Related
Is it possible to leave a function if a variable (inside the function) gets asssigned a certain value at any point. For example:
public class TestClass {
public int doSomething() {
int resultCode;
resultCode = checkFirstThing() //Returns 0 if succeed or 1 if not
//Exit if resultCode != 0
resultCode = checkSecondThing() //Returns 0 if succeed or 2 if not
//Exit if resultCode != 0
resultCode = checkThirdThing() //Returns 0 if succeed or 3 if not
//Exit if resultCode != 0
//do Something if all clauses succeeded
return resultCode
}
}
My problem is, that I don't want to add a if(resultCode != 0) return resultCode after each Check-Function.
I didn't find anythig myself, but as there are some very smart heads out there, I thought that mybe someone else knows a better way than my curren solution (guard clauses after each check).
I know what I want is propably not possible, but this Question is here to make sure.
Tanks for your help :)
You can write a higher order function for this. You essentially just want to get the result code of the first check that isn't 0, or 0 if all checks returned 0.
public static int checkAll(IntSupplier... resultCodeSuppliers) {
return Arrays.stream(resultCodeSuppliers)
.mapToInt(IntSupplier::getAsInt)
.filter(x -> x != 0)
.findFirst().orElse(0);
}
This works because stream operations are lazy. When I do findFirst, it will only run the checks that return 0, plus the first check that returns non-0. It won't run any more checks after that one, because I only asked it to findFirst.
Usage:
int resultCode = checkAll(
() -> checkFirstThing(),
() -> checkSecondThing(),
() -> checkThirdThing()
);
if (resultCode == 0) { // you only need this one check
// do the thing...
}
return resultCode;
You can use java.util.OptionalInt of Java 8.
public class TestClass {
public int doSomething() {
return OptionalInt.of(checkFirstThing())
.map(x -> x != 0 ? x : checkSecondThing())
.map(x -> x != 0 ? x : checkThirdThing())
.getAsInt();
}
}
However, comparisons to zero are unavoidable since you need boolean values instead of int values whatsoever.
Maybe you can create a wrapper function for the comparison to zero and use OptionalInt.empty() to avoid the ternary operators.
The correct way to do this is to have a result object (implemented in its own class). This object consists of a code, which is set by the called methods (like checkFirstThing), if the check is successful. The object furthermore contains a flag or another information, whether the check is successful at all, which is also set by your methods checkXXThings.
That way you do not mingle stuff like transactions, null checks, exceptions with your logic, which would be bad for readability and couples technical issues with process logic. The code is NOT shorter than your first idea to do a null check (since you do have to check the success flag), but more concise and expresses, what you want to check. The solution form #Naetmul does essentially the same (as long as you return an Optional.empty() for a failed checkXXThings method call).
One way that suddenly now, came to my mind is that you can make your methods to return 1 if operation succeed or throw a exception otherwise.
then you can put all your calls to methods inside a try...catch and then if any exception occur you simply return from catch statement.
good luck :)
public class TestClass {
public int doSomething() {
int resultCode;
try {
resultCode = checkFirstThing(); //Returns 1 if succeed
//Exit if exception thrown
resultCode = checkSecondThing(); //Returns 1 if succeed
//Exit if exception thrown
resultCode = checkThirdThing(); //Returns 1 if succeed
//Exit if exception thrown
} catch (/* kind of your exception */) { return 0; /* failure */ }
//do Something if all clauses succeeded
return resultCode;
}
}
You can change the checkX methods to return a boolean (true for success, false for failure), and move the error codes to the method that calls them (doSomething()):
public int doSomething() {
if (!checkFirstThing()) {
return 1;
} else if (!checkSecondThing()) {
return 2;
} else if (!checkThirdThing()) {
return 3;
} else {
return 0;
}
}
You can consider the framework of Spring to solve this situation. #see
spring.io
And using the annotation in which named #transactional on the method. It can lead to the method process success if all submethod return success without exceptions. Otherwise, It can lead to rollback the method process.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I get NullPointerException when validating object. I send to controller dto, and when validating it. I cant understan where is the problem because product that goes into validate method is not null, Validator code :
#Override
public void validate(Object o, Errors errors) {
Product product = (Product) o;
if (product.getTitle().isEmpty() || product.getTitle() == null) {
errors.rejectValue("title", "product.title", "Product title cant be empty");
}
if (product.getDescription().isEmpty() || product.getDescription() == null) {
errors.rejectValue("description", "product.description", "Product description cant be empty");
}
if (product.getPrice().isNaN() || product.getPrice()<=0 || product.getPrice() == null) {
errors.rejectValue("price", "product.price", "Product price is not valid");
}
if (product.getCategory()==null) {
errors.rejectValue("category", "product.category", "Product category is not valid");
}
}
and i get this
java.lang.NullPointerException
com.shop.validator.ProductValidator.validate(ProductValidator.java:27)
com.shop.controller.ProductController.createProduct(ProductController.java:82)
com.shop.controller.ProductController$$FastClassBySpringCGLIB$$c0d382c4.invoke()
org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
|| evaluates from left to right. So if you say
x == null || x.somethingSomething()
and if x is null, the first condition will catch the case, and it will prevent the method call on a null reference from happening. But if you say
x.somethingSomething() || x == null
and if x is null, it tries to evaluate the method call first, and throws an exception before it gets to the null check. Java (or any other computer language I'm aware of) isn't smart enough to "figure out" to do the null check first. It trusts the order you give it.
Similarly with &&:
if (x != null && x.something())
will do the null check at the right time, but
if (x.something() && x != null)
won't.
I am using Sonar and its giving me the suggestion "Expressions should not be too complex"
How can I make a better representation of below code?
Code
if (eDelivery != null && Boolean.parseBoolean(eDelivery.getReceiveConfirmationElectronically()) &&
!Boolean.parseBoolean(eDelivery.getInvalidEmailAddress()) && !Boolean.parseBoolean(eDelivery.getEmailUndeliverable()) &&
eDelivery.getUserEmailAddress() != null && !eDelivery.getUserEmailAddress().isEmpty()) {
// Implementation code
}
These conditions all relate to the eDelivery object, so deal with this there.
First, there's the question of why you're doing all these parseBoolean calls for properties that look like they should be boolean to start with. But okay, let's assume that you can't change that. Fine, so add 2ndary methods:
public class EDelivery {
public boolean isReceiveConfirmationElectronically() {
return Boolean.parseBoolean(getReceiveConfirmationElectronically())
}
// &etc...
Already that cleans it up considerably:
if (eDelivery != null && eDelivery.isReceiveConfirmationElectronically() &&
!eDelivery.isInvalidEmailAddress() && !eDelivery.isEmailUndeliverable() &&
eDelivery.getUserEmailAddress() != null && !eDelivery.getUserEmailAddress().isEmpty()) {
// Implementation code
But that doesn't address the number of conditions. So now:
// in EDelivery class
public boolean isEmailGood() {
return !isInvalidEmailAddress() && !isEmailUndeliverable() &&
getUserEmailAddress() != null && !getUserEmailAddress().isEmpty())
}
So now we're at:
if (eDelivery != null && eDelivery.isReceiveConfirmationElectronically() &&
eDelivery.isEmailGood()) {
// Implementation code
At this point you've met the requirement, but if you wanted to take it a little further:
// in EDelivery class
public boolean canSendElectronicConfirmation(){
return isEmailGood() && isReceiveConfirmationElectronically();
}
Which reduces your original if statement to
if (eDelivery != null && eDelivery.canSendElectronicConfirmation()) {
// Implementation code
I have a static method where I get a list of tweets and the name of a town as a parameter and I remove from the list whichever tweet did not originate from the town or the user that made it did not originate from the town.
Here is my code:
public static void removeIncorrectTowns(List<Status> tweets, final String town) {
if (town.isEmpty()) {
return;
}
Iterator<Status> it = tweets.iterator();
while (it.hasNext()) {
Status status = it.next();
if ((status.getPlace() == null && (status.getUser().getLocation() == null || !status.getUser().getLocation().equalsIgnoreCase(town)))
|| !status.getPlace().getName().equalsIgnoreCase(town)) {
it.remove();
}
}
}
The problem I have is that I got a NullPointerException at line 62 which is the line with it.remove().
How is it even possible for the iterator to be null? That alone makes no sense to me since the while loop checks if it.hasNext().
In the case that status.getPlace() is null and status.getUser().getLocation() is not null and does not equal town, you are going to get a NPE in the last part of the condition when status.getPlace().getName() is called.
I'm writing a method that should return the first item in an array belonging to a certain user. The class looks like this:
public MailItem getNextMailItem(String who)
{
return mailbox.get(who).pollFirst();
}
I need some sort of error handling in case the "who"-parameter is empty or null e.g
if (who != null && who.length() != 0)
But what if that turns out to be false?
your if block is something like that
public MailItem getNextMailItem(String who) {
MailItem item = null;
if (who != null && who.length() != 0) {
item = mailbox.get(who).pollFirst();
} else {
//show some error message or error log here
}
return item;
}
on filure your method will return null.
also read this Q&A
Returning null in the absence of a value would be an obvious solution:
public MailItem getNextMailItem(String who){
MailItem mailItem = null;
if (who != null && who.length() != 0){
mailItem = mailbox.get(who).pollFirst();
}
return mailItem;
}
But consider this:
If you communicate with null, your return value really is ambiguous. It can mean a lot of things. Instead, you could use Guava's Optional or the Null object pattern.
Using the Null pattern, you would define an instance that has a neutral behavior, possibly in your MailItem interface, and return it in case of the absence of a value:
public MailItem getNextMailItem(String who) {
MailItem mailItem = null;
if (who != null && who.length() != 0){
mailbox.get(who).pollFirst();
} else {
mailItem = MailItem.NULL_ITEM;
}
return mailItem;
}
This way - unless an unexpected exception happens - you can always be sure that getNextMailItem returns a valid instance of MailItem.
Simple solution is to return null. On the other side, check for null and handle accordingly.