(JAVA) Null Pointer Exception, I'm rather confused - java

So I've done a some readings on NullPointerExceptions in Java but I'm still not really understanding it completely.
why does this work?
if ((department != null && department.equals("COMP")) || (department != null && department.equals("COMM")))
{
this.department = department;
}
and also another method that worked was when I first checked for != null and then did a second nested if statement to then check for "COMP" or "COMM".
compared to the above, how come this one doesn't work?
if (department != null || department.equals("COMP")) || department.equals("COMM")))
{
this.department = department;
}
Like most, I don't like having found a solution by accident but not really understanding why it's a solution. I'm still very new to programming so I'm trying to understand what's actually happening underneath the hood. I understand things the easiest when given a metaphor to compare with, it'd really help if someone can explain it for me that way ><;;
Thank you guys very much!

The answer to your question is in the boolean algebra and how you are implementing the conditions
Doing this
((department != null && department.equals("COMP")) || (department != null && department.equals("COMM")))
is equivalent to doing
A&B | A&C that can be resumed to A&(B|C).... so A must be met AND either B OR C in order to execute the code...
so far so good.
the second condition
if (department != null || department.equals("COMP")) || department.equals("COMM")))
is equivalent to doing
A | B | C that can NOT be resumed/simplified to anything
.... so A must be met OR either B OR C in order to execute the code...
if A is null first condition fails, then java tries to check condition B but since B is null it explodes with a nice NullPointer Exception

Because of boolean logic and because of runtime optimization.
In a boolean sentence if all operands are AND and one sentence is False all the sentence is False. So when runtime evaluate the first sentence and discover that is false it doesn't evaluate the others AND sentence. Than for AND case, no NullPointerExceptions exception, that means try to access an object that is null, may happen if you check it first. Otherwise if the sentence contains Only OR operand, runtime have to evaluate all the sentence, so the Null pointer exception happens because the object is null, the first sentence in OR is safe because you can compare a null object to NULL, but the second is not, because you cannot access a null object property.

Related

How to properly handle if statements containing both null checks and non-null checks together in an OR expression [duplicate]

This question already has answers here:
Java logical operator short-circuiting
(10 answers)
Closed last month.
I have some code that does the following:
if(object == null || object.value.equals(" ")) {
// do something
}
else {
// do something else
}
The above seems dangerous to me because if I switched the order of the two conditions or changed this to an AND expression, the code will crash when object is null, but I also read somewhere that Java guarantees operands are evaluated from left to right. That said, I also read do not assume this to be true.
I am confused by all this conflicting advice and wondering whether the above code constitutes a bug. That said, what is the best way to recode this if indeed this is considered bad practice?
In Java && and || are short circuit (boolean!) operators. So everything works as assumed. No unnecessary evaluation running into an error. Some languages Name these and-then, or-else.
boolean newGraphRequired = graphNode == null
|| gaphNode.timeStamp() != moduleNode.timeStamp();
Conditions become more straightforward.
Use below piece of code -
if(object == null || (object != null && " ".equals(object.value))) {
// do something
}
else {
// do something else
}
Also Always keep constant values in left side of equals, it will prevent NPE.
For Above code if object is null or object.value is " "(space), it will go inside if otherwise it will go in else.

Java: Standards to use constant.equals(variable) [duplicate]

If I try to do a .equals() on a null string in java, a null pointer exception will be thrown. I am wondering, if I am trying to compare if a string is equal to some constant string, can I do the following:
MY_CONSTANT_STRING.equals(aStringVariable)
I know it will work, but is this just really poor code?
This is a standard Java idiom jokingly called a Yoda condition.
Personally I prefer to handle the null case explicitly, but the Yoda way is used a lot and any experienced Java programmer should be able to understand what is going on immediately. It's fine to use.
is this just really poor code?
No, this is the way many people would code the statement to avoid NPE.
What you've got is fine. It's even possible to use a String literal.
if( "value".equals(variable) ) {
...
If you don't like that, you can always explicitly check for null and equality, and combine the two checks with &&. The short circuiting of the operator will make sure you never get a NPE.
if( (variable != null) && variable.equals("value") ) {
...
I would keep the "CONSTANT.equals(possibleNull)" code without the null test only if it is a normal condition that the variable could be null - for instance because it just came out of a property map.
Similarly you can get away with not checking for null in instanceof-checks - like:
Food dinner = map.get("dinner");
if (dinner instanceof Soup) {
((Soup)blah).eat();
} // We don't care if it is a Fish or null
But if you really did not expect null, you should explicitly check for that in a separate if-test, and handle it appropriately. It's generally better to catch such data errors early rather than later.
Nope, it's usually done to avoid NPE. However, I usually prefer to do explicit check for null.
If you are concerned about the quality of your code, write a helper class that takes care of equality test:
public class ObjectHelper {
public static boolean testEquality(Object o1, Object o2) {
if (o1 == null && o2 == null) return true;
if (o1 == null) return false;
return o1.equals(o2);
}
}
Then use it like this:
if (ObjectHelper.testEquality(aStringVariable, My_CONSTANT_STRING))
Your so-called constant MIGHT stop being constant. It might be read from a configuration file some time in the future.

Is it possible to make Java code as groovy style

I'm trying to know whether we can write null check pointer in the same statement in Java, as we do in groovy? I've four places to check null. Can this be more simplified?
if(doc.getDocumentElement().getElementsByTagName("SEARCH-RESULT-ITEM") != null) {
if(doc.getDocumentElement().getElementsByTagName("SEARCH-RESULT-ITEM").item(0) != null) {
Node searchResultNode = doc.getDocumentElement().getElementsByTagName("SEARCH-RESULT-ITEM").item(0);
if(searchResultNode != null) {
}
}
}
as
doc.getDocumentElement()?.getElementsByTagName("SEARCH-RESULT-ITEM")?.item(0)
Is it possible
You asked if it is possible to write Groovy-like code in a regular Java project. The simple answer is no.
However, the statement can be simplified by combining the null checks into one condition. In addition, if doc.getDocumentElement().getElementsByTagName("SEARCH-RESULT-ITEM").item(0) is not null we don't need to check the local variable.
So we may end up with:
if (doc.getDocumentElement().getElementsByTagName("SEARCH-RESULT-ITEM") != null
&& doc.getDocumentElement().getElementsByTagName("SEARCH-RESULT-ITEM").item(0) != null {
Node searchResultNode = doc.getDocumentElement().getElementsByTagName("SEARCH-RESULT-ITEM").item(0);
}
Doing this reduces the number of IF statements from 3 to 1, and eliminates a redundant null check.
There is no safe dereference in Java.
It's generally bad practice to toss nulls around and Optional class may come to rescue as well ass checkNotNull at the beginning of the method, but nothing as fancy as Groovy one-liners.

difference between null != something and something != null

Is there a difference between null != something and something != null in Java. And if there is a difference then which one should I use and why??
There's no difference between null != something and something != null. You must be thinking about the person.getName().equals("john") and the "john".equals(person.getName()) difference: the first one will throw a NullPointerException if getName() returns null, while the second won't. But this is not applicable for the example of your question.
its probably comming from the so-called joda-conditions where you write "bla" == myVariable instead of myVariable == "bla" because it could happen to accidentially write myVariable = "bla" which returns "bla" in some languages but also assign "bla" to myVariable
I just want to point out that the "Yoda condition" rationale for doing this (in languages like C & C++) does not apply in this (Java) case.
Java does not allow general expressions to be used as statements, so both
something == null;
and
null == something;
would be compilation errors.
The types of something == null and something = null are different; boolean and some reference type respectively. In this case, it means that both:
if (something = null) {
...
}
and
if (null = something) {
...
}
would be compilation errors.
In fact, I can't think of a realistic example where null == something would be compilation error and something == null would not. Hence, it doesn't achieve anything in terms of mistake-proofing.
There is no difference, but some people use it for ease of readability in their code.
Point of view of performance there will be no difference, both sides of the operator are executed any way. But for a more readable code second one seems more readable
obj.getSomething().getAnotherThing().doSomething() != null
null != obj.getSomething().getAnotherThing().doSomething()
But if you are going to just compare a variable or parameter this is more readable
something != null
Of course this depends on sense of reader.
In java if we compare any, always we have to place variables at left hand side and values are placed at right hand side...
They are both the same there is no difference.

Looking through an array for an empty string

An array of Strings, names, has been declared and initialized. Write the statements needed to determine whether any of the the array elements are null or refer to the empty String. Set the variable hasEmpty to true if any elements are null or empty-- otherwise set it to false.
hasEmpty=false;
for (int i=0;i<names.length;i++)
if (names[i].trim().equals("") || names[i]==null)
hasEmpty=true;
Whats wrong with my code?
Calling trim() first will result in a NullPointerException should a member of the array be null. Reverse the order of the conditions - the short-circuiting nature of || will then ensure that trim is only called on a real String object.
Consider names[i].trim().
When names[i] is a String, you really have something like someString.trim() which works fine.
When names[i] is a null, however, you really have something like null.trim(). You've already discovered that null doesn't allow a trim() method. (In fact, I'm not even really sure what 'null' is.)
Therefore, you must check for null before you invoke trim().
When you have a && b, where a and b are expressions, the checks are made left-to-right and the parser stops as soon as the issue is settled. So for the logical and operator (&&), if a is false then b is never checked. This is what allows
if (a != null && a.trim().length() > 0) { ... }
to work. if a is null, the a.trim() part is not executed since it would be pointless from a logical point of view; the value of the conditional has been decided.
Similarly for
if (a == null || a.trim().length() == 0) { ... }
if a is null then the a.trim() part is never performed and we don't get an error.
You can use the Apache Commons Lang's isBlank() to check a String:
if (StringUtils.isBlank(names[i]) {
...
}
StringUtils.isBlank is checking if the String is null or empty (i.e. if it is equals to "" when all blank characters are removed).
It's throwing a Null Pointer Exception because you're trying to run a method on a null object:
if (names[i].trim().equals("") || names[i]==null)
So, anytime that names[] has ONE name that's null, it will throw the exception. One way to solve the problem is to switch the boolean statements in this if statement:
if (names[i]==null || names[i].trim().equals(""))

Categories

Resources