I currently have an enumlist. The enumlist gets filled at random, so there is a possibility that one has the value null. That is logical because it doesn't get filled.
The problem is further in my code I have:
if (player.Enumlist().get(CART_BLACK) > 0) {
}
Java throws a NullPointerException. Is there something I could add to the if-statement to prevent this error?
If get(CART_BLACK) may return null:
Get the value before the condition and replace it with a negative value if it's null:
Integer cartBlack = player.Enumlist().get(CART_BLACK);
if (cartBlack == null) cartBlack = -1;
if (cartBlack > 0) {
If player.Enumlist() may return null
Similar, but not quite identical:
final Enumlist list = player.Enumlist();
final int cartBlack = list == null ? -1 : list.get(CART_BLACK);
if (cartBlack > 0) {
You'll need to guard against nullity:
if(player.Enumlist().get(CART_BLACK) != null &&
player.Enumlist().get(CART_BLACK) > 0) {...}
or a more efficient version:
Integer temp = player.Enumlist().get(CART_BLACK);
if (temp != null && temp > 0){...}
if( player.Enumlist().get(CART_BLACK) != null && player.Enumlist().get(CART_BLACK) > 0) {
}
This will work because ifs are checked from left to right, and if one condition fails the rest won't be evaluated and you won't get the NPE.
Correcting the issue at the end makes the trick but it is not fine because it means that it may occur in other invocations. Besides, as a consequence, you may finish by overusing not null guards as you will never know if the null is a normal case.
So you should favor the use of Optional (Java 8 or Guava) as return rather than null to make your API clearer (it may return an empty thing so convey that) and more robust (the contained object has to be specifically unwrapped).
For example :
Optional<Integer> optValue = player.Enumlist().get(CART_BLACK);
optValue.filter(v -> v > 0)
.ifPresent( v -> ...);
You need to do Null Checking:
if (player == null || player.Enumlist () == null) {
throw new Exception("Player or Enumlist cannot be null");
}
You should also check that the Integer value is not null, but I guess that would be pretty weird if you wrote the code.
You are using get which could give you an IndexOutOfBoundsException eventually. You could check that using the size method or using streams.
If (player.Enumlist().size() > CART_BLACK && player.Enumlist().get(CART_BLACK) != null && player.Enumlist().get(CART_BLACK) > 0) {
//...
}
You may check for Null also handle the exception using try..catch block
try
{
if( player.Enumlist().get(CART_BLACK)!=null && player.Enumlist().get(CART_BLACK) > 0)
{
}
}
catch(NullPointerException)
{
//handle exception here
}
Related
Pardon me if this is a stupid question.. I was wondering if there is any support for following comparison in Java:
(a, b, c .... != null) in place for :
(a != null && b != null && c != null && d ! null and so on ..)
I was trying to make code more readable as my code which is almost unreadable due to multiple condition in single statement.
code :
variable = (rest.host != null && rest.payload != null
&& rest.lockQueue != null && rest.endpoint != null ) || rest.default.setState
|| rest.scheduler.locked && rest.scheduler.queue.isFull()
&& lastPayload.getActivity.status.executing ? onExecute(rest.payload) : wait(TIME);
If your elements are in a collection, use collection.stream().allMatch(x -> x != null). Actually, there's even a predicate for that: collection.stream().allMatch(Objects::nonNull).
If your elements aren't in a collection, you can still use Arrays.asList() to create an ad-hoc list from them. So, in your case:
Arrays.asList(rest.host, rest.payload, rest.lockQueue, rest.endpoint).stream().allMatch(Objects::nonNull)
EDIT: actually, as someone mentioned in another answer, there is a method that creates a stream directly, namely Stream.of(...). So:
Stream.of(rest.host, rest.payload, rest.lockQueue, rest.endpoint).allMatch(Objects::nonNull)
You could do something like this to make sure everything is not null, if using a Java version lower than 8. Otherwise I would go with the other people's answers using streams.
private boolean checkIfNotNull( Object ... objects ) {
for(int i = 0; i < objects.length; i++) {
if(objects[i] == null)
return false;
}
return true;
}
and you could pass in all the objects that you want to check if they are null.
then you can call this in the if statement such as
if( checkIfNotNull( a, b, c, d, e, f, g ) ) {
//do stuff
}
In java 8, it could be done as next Stream.of(a, b, c, d).allMatch(Objects::nonNull), it will return true if they are all non null.
I think if you want your code more readable, you should replace your comparisons with method calls that "says" what each comparison is.
Example:
if (isAllRight(a, b, c)) {
...
}
In other cases you can break them into single comparisons and check one by one:
if (a == NUL) {
return false;
}
if (b == NULL) {
return false;
}
return true;
I'm trying to figure out the best way of grabbing the smallest of two numbers when the numbers are attributes inside of two different objects. Each, but not both, of the objects can be null, which can lead to null pointer exceptions. Each object has their own getValue() method, which will return a Long value. There's the basic if/else that I'd prefer not to do:
if (obj1 != null && obj2 != null) { // neither object is null
minValue = obj1.getValue() <= obj2.getValue() ? obj1.getValue() : obj2.getValue();
} else if (obj1 == null && obj2 != null) { // only obj1 is null
minValue = obj2.getValue();
} else { // only obj2 is null (they can't both be null, so we don't need an if for the situation where they're both null)
minValue = obj1.getValue();
}
I've tried some other things:
// can throw null pointer exception
Collections.min(Arrays.asList(obj1.getValue(), obj2.getValue()));
// while both objects have a getValue() method, they are of different types, so mapping doesn't work
Collections.min(Arrays.asList(obj1, obj2)
.filter(obj -> obj != null)
.map(obj -> obj.getValue()) // this line will fail since the methods correspond to different objects
.collect(Collectors.toList()));
I feel like this should be a fairly easy problem, but my brain's not allowing it to work. There's due to be some min function where you can bipass a situation where the object can be null?
long minValue = Math.min(obj1 == null ? Long.MAX_VALUE : obj1.getValue(),
obj2 == null ? Long.MAX_VALUE : obj2.getValue());
I am not sure I fully understand your question, but if I do, something like this could work:
if(obj1 == null)
minValue = obj2.getValue();
else if(obj2 == null)
minValue = obj1.getValue();
else minValue = obj1.getValue() < obj2.getValue() ? obj1.getValue() : obj2.getValue();
You could have a method that takes in your ObjType, does a null check and returns Long.MAX_VALUE, or the value if it's null.
public Long getVal(ObjType val)
{
if(val != null)
{
return val.getValue();
}
return Long.MAX_VALUE;
}
then do
Math.min(obj1, obj2);
Findbugs is showing NP_NULL_ON_SOME_PATH for a line.
It says that there is a branch of statement that, if executed, guarantees that a null value will be dereferenced, which would generate a NullPointerException when the code is executed.
Of course, the problem might be that the branch or statement is infeasible and that the null pointer exception can't ever be executed; deciding that is beyond the ability of FindBugs.
Here is the code:
public int compare(Object o1, Object o2)
{
....
String sTypeName1 = row1.getFieldValue(OBJECT_TYPE_FIELD_NAME);
String sTypeName2 = row2.getFieldValue(OBJECT_TYPE_FIELD_NAME);
if (sTypeName1!= null && sTypeName1.indexOf("~") != -1)
{
sTypeName1 = m_oc.getString(sTypeName1);
}
if (sTypeName2!= null && sTypeName2.indexOf("~") != -1)
{
sTypeName2 = m_oc.getString(sTypeName2);
}
int cf = sTypeName1.compareTo(sTypeName2);
if (cf == 0)
{
cf = o1.toString().compareTo(o2.toString());
}
return cf;
}
It is showing 2 errors of same kind for the code:
int cf = sTypeName1.compareTo(sTypeName2);
Here it says that there is a possible null pointer dereference from the value loaded from sTypeName1.
So I had to put a null check before this code like:
if(sTypeName1 != null && sTypeName2 != null)
{
int cf = sTypeName1.compareTo(sTypeName2);
}
but the issue is not resolved. :(
Could anyone suggest a solution and also what is wrong with my approach?
Thanks a lot for going through my question :)
For me the issue is resolved. This code does not produce a bug report:
String sTypeName1 = row1.getFieldValue("qqq");
String sTypeName2 = row2.getFieldValue("www");
if (sTypeName1 != null && sTypeName1.indexOf("~") != -1) {
sTypeName1 = m_oc.getString(sTypeName1);
}
if (sTypeName2 != null && sTypeName2.indexOf("~") != -1) {
sTypeName2 = m_oc.getString(sTypeName2);
}
int cf = 0;
if (sTypeName1 != null && sTypeName2 != null) {
cf = sTypeName1.compareTo(sTypeName2);
}
if (cf == 0) {
cf = o1.toString().compareTo(o2.toString());
}
return cf;
Probably you did not recompile your code or did not perform the FindBugs analysis again.
From my experience this can be caused by situations like this:
Situation 1 - Findbugs will complain if you only set b under some conditions, such as if a is not null, then later reference b. If a could really be null, you need to handle what to do if b is null too as a result. If a is never null, remove the null check. Also, for me it identified the line where b was defined as the first problematic line, rather than when b.doSomething() is called.
if (a != null) {
b = a.getB();
}
b.doSomething();
Situation 2 - You nullcheck in one place, but not another. Nullcheck everywhere, or nowhere
if (x != null) {
x.doSomething1();
}
x.doSomething2();
Are these comparisons always safe from creating a NullPointer Exception ?
if( myObject == null || myObject.someMethod() == someValue )
{
if( myObject == null && myObject.getAlwaysTrue() )
{
}
}
Is there some directional precedence in java for condition evaluation, apart from short circuiting ?
UPDATE: I Know myObject.anything() will throw a NullPointer. Its just that I have come across such code by other programmers, and I want to know if there's a safe way of squeezing multiple checks along with a null check in a single condition. I'm looking for a good rule to stick to.
No, this line is not safe:
if( myObject == null && myObject.getAlwaysTrue() )
If you know that myObject is null then you shouldn't try to dereference it. If however you wrote this:
if( myObject != null && myObject.getAlwaysTrue() )
Then it would be safe. This is because && (and || for that matter) has short-circuit evaluation. If you write a && b and the expression a evaluates to false, then the expression b is not evaluated so it will not throw an exception. The left operand is always evaluated first.
Why not separate out the gating issue?
if (myObject != null) {
if ((myObject.someMethod() == someValue) && myObject.getAlwaysTrue()) {
}
}
if( myObject == null && myObject.getAlwaysTrue() )
This will cause you a NullPointerException when myObject is null
Wherever I can, I strive for less indentantion and complex "ifology". In your case I'd just write
if (myObject == null) return;
... go on knowing that myObject is not null...
If the myObject is null, myObject.getAlwaysTrue() in the second if statement will always result in NullPointerException.
In the case of || the if expression evaluates the boolean expressions until it finds the first one that's true.
With && the if expression evaluates the boolean expressions until it finds the first one that's false.
So in your case when myObject is null, you'll get the following evaluations:
First if:
myObject == null -> true
Second if:
myObject == null -> true
myObject.getAlwaysTrue() -> NullPointerException
This is not :
if( myObject == null && myObject.getAlwaysTrue() )
&& will check both conditions, myObject.getAlwaysTrue() will throw NullPointerException if myObject is null.
I have compareObjects method implemented as below
public static int compareObjects(Comparable a, Comparable b){
if (a == null && b == null){
return 0;
} else if (a == null && b != null){
return -1;
} else if (a != null && b == null){
return 1;
} else {
return a.compareTo(b);
}
}
When I run this through findBugs, I get this suggestion on the line return a.compareTo(b):
There is a branch of statement that, if executed, guarantees that a null value will be dereferenced, which would generate a NullPointerException when the code is executed. Of course, the problem might be that the branch or statement is infeasible and that the null pointer exception can't ever be executed; deciding that is beyond the ability of FindBugs. Due to the fact that this value had been previously tested for nullness, this is a definite possibility.
At this point a can never be null. Why does FindBugs show me this suggestion? How can I correct this; what is the correct way to implement compareObjects()?
I think it might be because you don't need the extra && statements. After the first if statement you already know that one of them is null.
public static int compareObjects(Comparable a, Comparable b){
if (a == null && b == null){
return 0;
} else if (a == null){
return -1;
} else if (b == null){
return 1;
} else {
return a.compareTo(b);
}
}
Looking at it again , try this code:
if (a == null && b == null){
return 0;
}
if (a == null){
return -1;
}
if (b == null){
return 1;
}
return a.compareTo(b);
It may be a limitation in FindBugs; I agree that you've covered all the bases, but your null-check is split across two different conditions. Now these conditions happen to be complementary, so at least one of them will fire if a is null, but depending how sophisticated FindBugs is, it may not recognise this.
Two options here, then:
Just ignore the FindBugs warning. Due to its nature it will raise some false positives from time to time, so don't feel like you have to rewrite your code to make it 100% happy if you don't think the rewrite is worthwhile on its own merits.
You can use the #SuppressWarnings annotation to actually communicate this to FindBugs, if you want the report to show a nice big zero at the end. See this question for an example.
Restructure the condition so that the nullity check on a is more explicit, by nesting if blocks:
if (a == null) {
return b == null ? 0 : -1;
}
return b == null ? 1 : a.compareTo(b);
Depending on your tastes and style that might be a better rewrite anyway, in that is more clearly says "if a is null, do this calculation and return it, otherwise do this calculation". You can of course change the ternary condition into another if-else block if you prefer that.