The other day I saw a question on a forum in which it was noted that the following Apex code fails with a null exception error:
Boolean testVal = null;
if ( testVal )
System.debug( ‘Testval is true.’ );
System.debug( ‘Testval is false.’ );
This is somewhat unexpected in that in almost every other language, a null value in a Boolean variable is considered False.
In Apex, primitive variables always support a null value in addition to their expected values. Thus if you enter the following code into the developer console:
You’ll see that they all come out as true. And if you try to access any method on the object, you’ll get a null reference exception.
Boolean variables in Apex are thus consistent with other primitive data types.
Where it gets interesting is when you look at how you might use a Boolean value in code.
Let’s say you have an uninitialized Boolean variable b;
if(b) … will fail with a null reference exception
if(!b)… will fail with a null reference exception
Fair enough, but now consider the following two statements:
if(b!=true) system.debug(‘b is not true’);
if(b!=false) system.debug(‘b is not false’);
The result will be:
b is not true
b is not false
Well now, everyone knows that a real Boolean variable can’t be ‘not true’ (which is false) and ‘not false’ (which is true) at the same time.
Which means, to put it bluntly, that a Boolean variable in Apex is not really a true Boolean variable – at least as far as purists would be concerned.
Fortunately, I’m not much of a purist, so the real concern is what this means in practice.
First – always initialize your variables! This is especially true for those of you coming from .NET, which kindly initializes value type variables for you.
Second, test for null values where appropriate, even if you are using primitive data types.
Third, the safest comparison for Booleans is always against true – i.e. b == true or b != true. if you do this consistently, any null values that do sneak in will be treated as false. But does this mean you should always compare Booleans against True? Not necessarily – because you might want to catch those null reference exceptions to detect uninitialized variables or failures to check against null values.
It does mean you should never compare against false –
because in Apex b!= false doesn’t mean b is always true.
This is Visualforce, not Apex, but it’s worth noting that the behavior of comparisons involving null values is changing in Winter ’13. Search for “Changes to Expression Evaluation with Null Values” in the release notes (https://na1.salesforce.com/help/doc/en/salesforce_winter13_release_notes.pdf) for details.
Absolutely correct. As you noted, I focused entirely on Apex here. As I read it, the changes, if anything, bring VisualForce behavior closer to Apex behavior.
I suspect the way to look at it is that there really aren’t any primitive types in Apex.
Compare to java. In Java you have the “Boolean” class and “boolean” primitive type. Apex as only the class.
I don’t know how many times I typed “int” in Java and had the IDE turn it red or the compiler yell at me as there is no “int” primitive type in Apex, only the “Integer” class.
The value is neither true or false cause it is equal to null.
If you check for ‘= true’ or ‘= false’, it wont work anyways.
So ‘!= true’ is not false and ‘!= false’ is not true.
I’m not sure if you’re agreeing or disagreeing with me, since I’m not sure what value you’re referring to. But I stand by my recommendations 🙂
But if you have it as a Sobject field, it can not be null. For example if we have a custom object CustObj__c with checkbox Active__c.
CustObj__c c = new CustObj__c();
c.Active__c = null;
Both of this debugs will output “false” and not “null”
Still I always start with “myBoolean == true” or “myBoolean != true” as you never know how code gets refactored down the line to suddenly have null issues… Small compromise in readability, huge potential saving in time/energy later on. And that’s from someone not sticking to too many rules… I just really do not want to debug problems coming from it years after.