In Java, you would usually say that
if(someBool != false)
is the same as
if(someBool)
But what if someBool is not of type boolean but Boolean, and its value is null?
If you want to handle Boolean instances as well as primitives and be null-safe, you can use this:
if(Boolean.TRUE.equals(someBool))
It will throw a NullPointerException (autounboxing of null throws NPE).
But that only means that you must not allow a null value. Either use a default, or don't use autounboxing and make a non-null check. Because using a null value of a boolean means you have 3, not 2 values. (Better ways of handling it were proposed by Michael and Tobiask)
Use ApacheCommons BooleanUtils.isTrue() or .isFalse()
If someBool is Boolean
if (someBull != null && someBull) {
//Yeah, true.
}
Since Boolean can be null make sure you avoid NullPointerException by checking for not null.
I did a little test:
Boolean o = null;
try {
System.out.println(o ? "yes" : "no");
} catch (Exception e) {
e.printStackTrace();
}
try {
System.out.println((o != false) ? "yes" : "no");
} catch (Exception e) {
e.printStackTrace();
}
The output is surprising:
java.lang.NullPointerException
at btest.main(btest.java:10)
java.lang.NullPointerException
at btest.main(btest.java:15)
The first NPE is to be expected, because o will be autounboxed (and that fails because it's null). The second happens for the same reason, but it doesn't feel natural. Anyway, the solution is to do:
System.out.println(!Boolean.FALSE.equals(o) ? "yes" : "no");
You can however compare a null Boolean with a Boolean instance. For example :
Boolean myBool = null;
System.out.println(myBool == Boolean.FALSE);
System.out.println(myBool == Boolean.TRUE);
prints :
false
false
Good illustrations of the difference between the primitive boolean & the object Boolean. The former can be only true or false. The latter can be true, false, or unknown/undefined. (i.e., null). Which you use depends on whether you want to deal with two use cases or three.
It's old, but Boolean.valueOf(null) is false, just like Boolean.valueOf(false) is false.
Actually the Boolean constructor accepts null, returns FALSE and doesn't throw a NullPointerTantrum.
new Boolean(null);
<false>
This has the added bonus of also giving a thruthy response to the string "true" which is not the case for Boolean.TRUE.equals but we are more restricted again having only constructors for Strings and Booleans.
Something you can overcome with string concatenation, which is also null-proof.
new Boolean(""+null);
<false>
new Boolean(""+false);
<false>
new Boolean(""+new Object());
<false>
new Boolean(""+6);
<false>
new Boolean(""+new Integer(9));
<false>
Ensuring that all the TRUE options, available in java, still remains.
new Boolean(""+true);
<true>
new Boolean(""+"true");
<true>
If it's Java 7+ you can use
import java.util.Objects;
And
if (Objects.equals(someBool, true))
As Boolean will give you an object, you must always check for NULL before working on the object
If its null then you'll get a NullPointerException
Related
in my code I have the following code involving a multiply() operation on twoBigDecimal values
walletsDTOList.stream().forEach( (WalletDTO wallet) -> {
try {
ConversionPriceDTO conversionPriceDTO = coingeckoInfoService.getCoinPrice(wallet.getCoin().getName(),targetCurrency);
BigDecimal conversionRate = conversionPriceDTO.getPrice();
conversionPriceDTO.setPrice(wallet.getAmount().multiply(conversionRate));
wallet.setConvertedCurrencyAmountInfo(conversionPriceDTO);
} catch (JsonProcessingException | BindingException e) {
throw new RuntimeBindingException(e.getMessage());
}
});
This line:
conversionPriceDTO.setPrice(wallet.getAmount().multiply(conversionRate));
Now my problem is that the wallet.getAmount() coming from the DB and it could be NULL. The problem is that in case of NULL value I obtain the following exception:
java.lang.NullPointerException: Cannot invoke "java.math.BigDecimal.multiply(java.math.BigDecimal)" because the return value of "com.easydefi.users.dto.WalletDTO.getAmount()" is null
I need to toughen up this operation. For my NULL value equals to 0 so in this case the multiply operation must return 0.
What can be a smart way to do it? My idea was to put the previous line (containing the multiply() operation) into a try catch and in case of NullPointerException set 0.
Is it good or can I do better?
If you encounter a different NPE in the same block of code, catching it and assuming that it was thrown because getAmount returned null will hide some other bug.
Either change getAmount to never return null, or do something like:
final BigDecimal walletAmount = wallet.getAmount();
conversionPriceDTO.setPrice(
walletAmount == null ? BigDecimal.ZERO
: walletAmount.multiply(conversionRate)
);
Something like this may help:
final BidDecimal amount = Optional.ofNullable(wallet.getAmount()).orElse(BigDecimal.ZERO);
...
I look for a more elegant solution of this code:
var first = Optional.ofNullable(a);
var second = Optional.ofNullable(b);
if ((unit.isPresent() && value.isEmpty()) || (value.isPresent() &&
unit.isEmpty())) {
throw new ExpWhatever();
}
Conditions are:
if both optionals are null -> ok, no error/excpt.
if one of the given optionals is present the other must not be empty too (otherwise: excpt.)
Thanks for any ideas or help.
It sounds like it's an error for isPresent() to be true for exactly one of them - so XOR works well:
if (unit.isPresent() ^ value.isPresent()) {
// Throw an exception
}
If you want both optionals to be either present or empty (i.e. they have the same "emptiness" state), you could use this:
if (unit.isPresent() != value.isPresent()) {
//throw an exception
}
I'm looking for a solution to check that each items in a collection have the field expectedNullField null.
The following doesn't work:
assertThat(aCollection).extracting("expectedNullField").isNull();
Note that the following works as expected:
assertThat(aCollection).extracting("expectedNotNullField").isNotNull();
Anybody to help me ?
Thanks.
If you know the size (let's say it is 3) you can use
assertThat(aCollection).extracting("expectedNullField")
.containsOnly(null, null, null);
or if you are only interested in checking that there is a null value
assertThat(aCollection).extracting("expectedNullField")
.containsNull();
Note that you can't use:
assertThat(aCollection).extracting("expectedNullField")
.containsOnly(null);
because it is ambiguous (containsOnly specifying a varargs params).
I might consider adding containsOnlyNullElements() in AssertJ to overcome the compiler error above.
You can use a Condition
Condition<YourClass> nullField = new Condition<>("expecting field to be null") {
#Override
public boolean matches(YourClass value) {
return value.getField() == null;
}
};
assertThat(aCollection).have(nullField);
which might be easier to read than the other solution
assertThat(aCollection).filteredOn("expectedNullField", not(null)).isEmpty();
Here is the Java code:
public static boolean anyEqual(Object needle, Object... haystack) {
if(needle == null || haystack == null) {
return false;
}
if(haystack.length == 0) {
return false;
}
for(Object match : haystack) {
if(match != null && needle.getClass() == match.getClass() && needle.equals(match)) {
return true; // warning from IntelliJ here, 'contract clause !null, null -> false is violated'
}
}
return false;
}
Does anyone have any idea why this is being shown? contract clause !null, null -> false is violated? Thanks!
IntelliJ 14.0.2 build: 139.659
Screenshot:
IntelliJ is inferring the formal contract of your method to be this:
null, _ -> false; !null, null -> false
What this actually means:
The first contract specifies that, so long as the first parameter is null, it will return false. This is observed by your first if statement:
if(needle == null || haystack == null) {
return false;
}
The second contract specifies that, if the second parameter is null, then it will return false. This is also specified by the same if statement above.
My gut is telling me that IntelliJ is having some trouble discerning what the loop's formal contract is in addition to all of the above, although it'd be as simple as another condition in the contract expression.
for(Object match : haystack) {
if(match != null && needle.getClass() == match.getClass() && needle.equals(match)) {
return true;
}
}
Let's briefly go through this.
The enhanced-for statement won't fire if haystack is of length 0, so that's something to take into consideration.
The elements inside of the array could be null, and I'm not entirely sure that IntelliJ's static analysis covers that piece yet.
We've established already that needle must be non-null, so there's nothing violating the contract at that line.
If we have a scenario in which match != null && needle.getClass() == match.getClass() && needle.equals(match) is true, we return true. Otherwise, we return false.
There's nothing that I can see in the formal documentation that gives us the expression we require to say, "hey - we're checking elements of an array!"; it may be the case that the analysis is tripping up on the fact that we're returning true in spite of what we stated above (since haystack is non-null).
Allow me to stress this point:
haystack has to be non-null in order for you to enter into the enhanced-for. Your code will not work otherwise.
All in all, I wouldn't worry about it. Better yet, file a bug against it so that this sort of thing could be fixed or expanded upon.
This looks like an IntelliJ bug to me, since by removing the static keyword from the method the warning disappears.
Something must be confusing the static analysis here. One can always submit this to youtrack so jetbrains devs can look at it.
Someone already reported this issue Here
(tested on v14.0.3)
This message is being shown because IntelliJ checks for method contract violations. It's a relatively new feature, read more at https://www.jetbrains.com/idea/features/annotation_java.html
Very basic question I suppose, I just wanted to know how this code is read:
return someboolean ? new someinstanceofsomething() : someotherboolean ? new otherinstance() : new third instance();
I guess now as I'm writing it I kind of understand the statement. It returns option one if true but then does another boolean check if false and returns one of the two remaining options? I'm going to continue to leave this question because I have not seen it before and maybe others have not as well.
Could you go on indefinitely with ternary inside of ternary operations?
Edit: Also why is this/is this not better for code than using a bunch of if statements?
It is defined in JLS #15.25:
The conditional operator is syntactically right-associative (it groups right-to-left). Thus, a?b:c?d:e?f:g means the same as a?b:(c?d:(e?f:g)).
In your case,
return someboolean ? new someinstanceofsomething() : someotherboolean ? new otherinstance() : new third instance();
is equivalent to:
return someboolean ? new someinstanceofsomething() : (someotherboolean ? new otherinstance() : new third instance());
Ternary operators are right-associative. See assylias's answer for the JLS reference.
Your example would translate to:
if (someboolean) {
return new someinstanceofsomething();
} else {
if (someotherboolean) {
return new otherinstance();
} else {
return new thirdinstance()
}
}
And yes, you can nest these indefinitely.