// Life is an interface!
if (!Life.isValid()) {
// handle the problem e.g. retries etc...
}
Regards,
Pho
42
Yes and no, depending on your semantics. Yes, that's exactly what it means, but no, that's not at all what Bloch's item is about. There's a subtle difference between "an empty data set" and "no data". The problem is that an awful lot of developers confuse the two and use a null value inappropriately.Originally posted by Jeroen Wenting:
Personally I don't believe in not using null to indicate no data, after all that's exactly what null means...
Not so. The JVM will probably inline such methods if called often - and it's very, very unlikely that it would be a bottleneck in the first place. And code that uses nulls inappropriately is in my experience bulkier, harder to read and more bug-prone. Code that handles an array (or collection) will usually work fine even when you stick in a zero-length result. If you'd use nulls, you better stick in checks everywhere, in every code path no matter how obscure, or it's NPE galore.The latter is a simple comparison of a reference, the latter involves method calls thus making the code harder to read and fractionally slower (more than fractionally slower if there's a lot of such comparisons compared to the length of the code filling the collection and handling the result).
Peter den Haan | peterdenhaan.com | quantum computing specialist, Objectivity Ltd
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Regards,
Pho
Originally posted by Peter den Haan:
We could simply assign null to our caches, but that would litter the code with tests whether the cache is null or not. A waste of space and a source of bugs.
And code that uses nulls inappropriately is in my experience bulkier, harder to read and more bug-prone. Code that handles an array (or collection) will usually work fine even when you stick in a zero-length result. If you'd use nulls, you better stick in checks everywhere, in every code path no matter how obscure, or it's NPE galore.
"Write beautiful code; then profile that beautiful code and make little bits of it uglier but faster." --The JavaPerformanceTuning.com team, Newsletter 039.
Sticking with the example, the very fact that the cache might be null and you have to check for that whenever you use it is a source of bugs - after all, you only need to forget once, in some obscure corner of your code. All that additional clutter won't help either.Originally posted by David Hibbs:
I fail to see how checking for nulls would be a source of bugs--I hope you are implying that the *setting* of the cache to nulls rather than the null checks themselves.
I beg to differ. Paranoia programming like this is a very good idea on external interface points[1], but a bad habit otherwise. Rather, establish clear contracts. I have a simple understanding with the team: if you're not clear about the contract, read the javadoc. If that fails, read the unit tests. If the contract is ambiguous, disambiguate it and document the fact.IMHO, it is a good idea to always check for nulls--especially when someone other than you is going to be maintaining the code (or the API you are using).
If your newcomer tucks into the code without first examining the contract then God help you. Or, hopefully, your unit tests may help you. You'll have much bigger problems than a null check.2 years from now, some newcomer to your code will go make an enhancement or fix and change the code to return a null in some obscure case because they don't know your pattern.
If only it were so simple. How much harder isTo read thanAnd how much harder once it's embedded in a method with other code, other code that itself bloats in similar ways? How much harder is it if, while modifying code, you have to keep track of where you are within a null check (so you don't need to check again) and outside one? Of course a single simple null check does not represent significant complexity, I would argue that the cumulative effect is definitely significant.Bulkier maybe, but how hard is it to read (myObj!=null) ?!?!
Peter den Haan | peterdenhaan.com | quantum computing specialist, Objectivity Ltd
Originally posted by Peter den Haan:
Sticking with the example, the very fact that the cache might be null and you have to check for that whenever you use it is a source of bugs - after all, you only need to forget once, in some obscure corner of your code.
[1]When using other code, especially when contracts aren't clear, it might return null when it shouldn't and it's best to anticipate that.
"Write beautiful code; then profile that beautiful code and make little bits of it uglier but faster." --The JavaPerformanceTuning.com team, Newsletter 039.
Exactly the other way around - the cache knows what factory to use in case of a cache miss, so that (1) client code can simply call cache.get(key) and not care if it's a cache hit or miss and (2) factory code can simply create the object and not care about caching at all. Have the cache do as much as possible. The code I showed illustrates what you'd end up doing if the cache were no in lieu of using a NullCache: call the factory by hand.Originally posted by David Hibbs:
[...] This implies that cache is a true cache that can hit or miss and is, in truth, ignorant of how to create the objects it contains--this is why you have a factory, I would assume. On a tangent, wouldn't it be be wiser to have a factory first go to the cache before creating a new object and query the factory rather than querying the cache?
Each object type typically has its own cache - but multiple caches can share a single strategy. But we digress. BadlyThis allows you to change caching rules at the factory level rather than the application level, amont other things...)
As soon as you do that you're changing the contract. Doing without assessing the impact of the change and making corresponding modifications to client code is a recipe for disaster. Really, I don't see how this is germane to the entire null issue. It is just one out of the million ways a contract might be changed. Why single it out for your worries? What makes it so special?Javadoc and unit tests can be changed.
See above. Besides, Checkstyle does a good job keeping a close watch over hereJavadoc has a nasty habit of becoming out of date without close watch.
Presumably if you have 'em, you utilise the investment by running 'emUnit tests are only good if run.
Although we're clearly not as far apart as it seemed at first glance, we're not that close either. This was about third party code, and particularly where the contracts aren't clear: if the contract unambiguously states that a returned value won't be null I'll accept it as such. Which leaves the vast majority of code that wasn't written by me and/or won't be maintained by me, and is thereby miles away from "always check return values for nulls."Unless I misread my writing, this is exactly what I was saying. "IMHO, it is a good idea to always check for nulls--especially when someone other than you is going to be maintaining the code (or the API you are using)" although perhaps I should qualify this a bit as saying "always check return values for nulls."
Why indeed? Because if an API can suddenly change in arbitrary and undocumented ways, you're stuffed. It is too unstable to use.[...] why should I trust those maintaining the API to maintain a contract that they may think is outdated?
Peter den Haan | peterdenhaan.com | quantum computing specialist, Objectivity Ltd
Originally posted by Peter den Haan:
Exactly the other way around - the cache knows what factory to use in case of a cache miss
As soon as you do that you're changing the contract. Doing without assessing the impact of the change and making corresponding modifications to client code is a recipe for disaster.
Besides, Checkstyle does a good job keeping a close watch over here.
I'm obviously missing something here. Out of all the things that might change in a contract, why do we specifically have to be anticipate the eventuality that null values might pop out of methods that previously vowed never to return them?
Which leaves the vast majority of code that wasn't written by me and/or won't be maintained by me, and is thereby miles away from "always check return values for nulls."
Client code should be distrusted. So yes, you probably do check null arguments and throw a nice exception if you find them; just like you distrust the object types in collections and so on. It's part of making your API robust and user-friendly. That doesn't involve relaxing your contracts though, just being precise in reporting contract violations.
For library code, a level of trust needs to be established on a case by case basis.
"Write beautiful code; then profile that beautiful code and make little bits of it uglier but faster." --The JavaPerformanceTuning.com team, Newsletter 039.
We want an alternate way of informing the client (vis-�-vis null checks) that we found nothing that matches the search parameter - in this case, lifeId.
SCJP 1.4, SCWCD 1.3, SCBCD 1.3
Peter den Haan | peterdenhaan.com | quantum computing specialist, Objectivity Ltd
The only thing that kept the leeches off of me was this tiny ad:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
|