Static default method for not initialized Classes - java

sometimes it would be convenient to have an easy way of doing the following:
Foo a = dosomething();
if (a != null){
if (a.isValid()){
...
}
}
My idea was to have some kind of static “default” methods for not initialized variables like this:
class Foo{
public boolean isValid(){
return true;
}
public static boolean isValid(){
return false;
}
}
And now I could do this…
Foo a = dosomething();
if (a.isValid()){
// In our example case -> variable is initialized and the "normal" method gets called
}else{
// In our example case -> variable is null
}
So, if a == null the static “default” methods from our class gets called, otherwise the method of our object gets called.
Is there either some keyword I’m missing to do exactly this or is there a reason why this is not already implemented in programming languages like java/c#?
Note: this example is not very breathtaking if this would work, however there are examples where this would be - indeed - very nice.

It's very slightly odd; ordinarily, x.foo() runs the foo() method as defined by the object that the x reference is pointing to. What you propose is a fallback mechanism where, if x is null (is referencing nothing) then we don't look at the object that x is pointing to (there's nothing its pointing at; hence, that is impossible), but that we look at the type of x, the variable itself, instead, and ask this type: Hey, can you give me the default impl of foo()?
The core problem is that you're assigning a definition to null that it just doesn't have. Your idea requires a redefinition of what null means which means the entire community needs to go back to school. I think the current definition of null in the java community is some nebulous ill defined cloud of confusion, so this is probably a good idea, but it is a huge commitment, and it is extremely easy for the OpenJDK team to dictate a direction and for the community to just ignore it. The OpenJDK team should be very hesitant in trying to 'solve' this problem by introducing a language feature, and they are.
Let's talk about the definitions of null that make sense, which definition of null your idea specifically is catering to (at the detriment of the other interpretations!), and how catering to that specific idea is already easy to do in current java, i.e. - what you propose sounds outright daft to me, in that it's just unneccessary and forces an opinion of what null means down everybody's throats for no reason.
Not applicable / undefined / unset
This definition of null is exactly how SQL defines it, and it has the following properties:
There is no default implementation available. By definition! How can one define what the size is of, say, an unset list? You can't say 0. You have no idea what the list is supposed to be. The very point is that interaction with an unset/not-applicable/unknown value should immediately lead to a result that represents either [A] the programmer messed up, the fact that they think they can interact with this value means they programmed a bug - they made an assumption about the state of the system which does not hold, or [B] that the unset nature is infectuous: The operation returns the notion 'unknown / unset / not applicable' as result.
SQL chose the B route: Any interaction with NULL in SQL land is infectuous. For example, even NULL = NULL in SQL is NULL, not FALSE. It also means that all booleans in SQL are tri-state, but this actually 'works', in that one can honestly fathom this notion. If I ask you: Hey, are the lights on?, then there are 3 reasonable answers: Yes, No, and I can't tell you right now; I don't know.
In my opinion, java as a language is meant for this definition as well, but has mostly chosen the [A] route: Throw an NPE to let everybody know: There is a bug, and to let the programmer get to the relevant line extremely quickly. NPEs are easy to solve, which is why I don't get why everybody hates NPEs. I love NPEs. So much better than some default behaviour that is usually but not always what I intended (objectively speaking, it is better to have 50 bugs that each takes 3 minutes to solve, than one bug that takes an an entire working day, by a large margin!) – this definition 'works' with the language:
Uninitialized fields, and uninitialized values in an array begin as null, and in the absence of further information, treating it as unset is correct.
They are, in fact, infectuously erroneous: Virtually all attempts to interact with them results in an exception, except ==, but that is intentional, for the same reason in SQL IS NULL will return TRUE or FALSE and not NULL: Now we're actually talking about the pointer nature of the object itself ("foo" == "foo" can be false if the 2 strings aren't the same ref: Clearly == in java between objects is about the references itself and not about the objects referenced).
A key aspect to this is that null has absolutely no semantic meaning, at all. Its lack of semantic meaning is the point. In other words, null doesn't mean that a value is short or long or blank or indicative of anything in particular. The only thing it does mean is that it means nothing. You can't derive any information from it. Hence, foo.size() is not 0 when foo is unset/unknown - the question 'what is the size of the object foo is pointing at' is unanswerable, in this definition, and thus NPE is exactly right.
Your idea would hurt this interpretation - it would confound matters by giving answers to unanswerable questions.
Sentinel / 'empty'
null is sometimes used as a value that does have semantic meaning. Something specific. For example, if you ever wrote this, you're using this interpretation:
if (x == null || x.isEmpty()) return false;
Here you've assigned a semantic meaning to null - the same meaning you assigned to an empty string. This is common in java and presumably stems from some bass ackwards notion of performance. For example, in the eclipse ecj java parser system, all empty arrays are done with null pointers. For example, the definition of a method has a field Argument[] arguments (for the method parameters; using argument is the slightly wrong word, but it is used to store the param definitions); however, for methods with zero parameters, the semantically correct choice is obviously new Argument[0]. However, that is NOT what ecj fills the Abstract Syntax Tree with, and if you are hacking around on the ecj code and assign new Argument[0] to this, other code will mess up as it just wasn't written to deal with this.
This is in my opinion bad use of null, but is quite common. And, in ecj's defense, it is about 4 times faster than javac, so I don't think it's fair to cast aspersions at their seemingly deplorably outdated code practices. If it's stupid and it works it isn't stupid, right? ecj also has a better track record than javac (going mostly by personal experience; I've found 3 bugs in ecj over the years and 12 in javac).
This kind of null does get a lot better if we implement your idea.
The better solution
What ecj should have done, get the best of both worlds: Make a public constant for it! new Argument[0], the object, is entirely immutable. You need to make a single instance, once, ever, for an entire JVM run. The JVM itself does this; try it: List.of() returns the 'singleton empty list'. So does Collections.emptyList() for the old timers in the crowd. All lists 'made' with Collections.emptyList() are actually just refs to the same singleton 'empty list' object. This works because the lists these methods make are entirely immutable.
The same can and generally should apply to you!
If you ever write this:
if (x == null || x.isEmpty())
then you messed up if we go by the first definition of null, and you're simply writing needlessly wordy, but correct, code if we go by the second
definition. You've come up with a solution to address this, but there's a much, much better one!
Find the place where x got its value, and address the boneheaded code that decided to return null instead of "". You should in fact emphatically NOT be adding null checks to your code, because it's far too easy to get into this mode where you almost always do it, and therefore you rarely actually have null refs, but it's just swiss cheese laid on top of each other: There may still be holes, and then you get NPEs. Better to never check so you get NPEs very quickly in the development process - somebody returned null where they should be returning "" instead.
Sometimes the code that made the bad null ref is out of your control. In that case, do the same thing you should always do when working with badly designed APIs: Fix it ASAP. Write a wrapper if you have to. But if you can commit a fix, do that instead. This may require making such an object.
Sentinels are awesome
Sometimes sentinel objects (objects that 'stand in' for this default / blank take, such as "" for strings, List.of() for lists, etc) can be a bit more fancy than this. For example, one can imagine using LocalDate.of(1800, 1, 1) as sentinel for a missing birthdate, but do note that this instance is not a great idea. It does crazy stuff. For example, if you write code to determine the age of a person, then it starts giving completely wrong answers (which is significantly worse than throwing an exception. With the exception you know you have a bug faster and you get a stacktrace that lets you find it in literally 500 milliseconds (just click the line, voila. That is the exact line you need to look at right now to fix the problem). It'll say someone is 212 years old all of a sudden.
But you could make a LocalDate object that does some things (such as: It CAN print itself; sentinel.toString() doesn't throw NPE but prints something like 'unset date'), but for other things it will throw an exception. For example, .getYear() would throw.
You can also make more than one sentinel. If you want a sentinel that means 'far future', that's trivially made (LocalDate.of(9999, 12, 31) is pretty good already), and you can also have one as 'for as long as anyone remembers', e.g. 'distant past'. That's cool, and not something your proposal could ever do!
You will have to deal with the consequences though. In some small ways the java ecosystem's definitions don't mesh with this, and null would perhaps have been a better standin. For example, the equals contract clearly states that a.equals(a) must always hold, and yet, just like in SQL NULL = NULL isn't TRUE, you probably don't want missingDate.equals(missingDate) to be true; that's conflating the meta with the value: You can't actually tell me that 2 missing dates are equal. By definition: The dates are missing. You do not know if they are equal or not. It is not an answerable question. And yet we can't implement the equals method of missingDate as return false; (or, better yet, as you also can't really know they aren't equal either, throw an exception) as that breaks contract (equals methods must have the identity property and must not throw, as per its own javadoc, so we can't do either of those things).
Dealing with null better
There are a few things that make dealing with null a lot easier:
Annotations: APIs can and should be very clear in communicating when their methods can return null and what that means. Annotations to turn that documentation into compiler-checked documentation is awesome. Your IDE can start warning you, as you type, that null may occur and what that means, and will say so in auto-complete dialogs too. And it's all entirely backwards compatible in all senses of the word: No need to start considering giant swaths of the java ecosystem as 'obsolete' (unlike Optional, which mostly sucks).
Optional, except this is a non-solution. The type isn't orthogonal (you can't write a method that takes a List<MaybeOptionalorNot<String>> that works on both List<String> and List<Optional<String>>, even though a method that checks the 'is it some or is it none?' state of all list members and doesn't add anything (except maybe shuffle things around) would work equally on both methods, and yet you just can't write it. This is bad, and it means all usages of optional must be 'unrolled' on the spot, and e.g. Optional<X> should show up pretty much never ever as a parameter type or field type. Only as return types and even that is dubious - I'd just stick to what Optional was made for: As return type of Stream terminal operations.
Adopting it also isn't backwards compatible. For example, hashMap.get(key) should, in all possible interpretations of what Optional is for, obviously return an Optional<V>, but it doesn't, and it never will, because java doesn't break backwards compatibility lightly and breaking that is obviously far too heavy an impact. The only real solution is to introduce java.util2 and a complete incompatible redesign of the collections API, which is splitting the java ecosystem in twain. Ask the python community (python2 vs. python3) how well that goes.
Use sentinels, use them heavily, make them available. If I were designing LocalDate, I'd have created LocalDate.FAR_FUTURE and LocalDate_DISTANT_PAST (but let it be clear that I think Stephen Colebourne, who designed JSR310, is perhaps the best API designer out there. But nothing is so perfect that it can't be complained about, right?)
Use API calls that allow defaulting. Map has this.
Do NOT write this code:
String phoneNr = phoneNumbers.get(userId);
if (phoneNr == null) return "Unknown phone number";
return phoneNr;
But DO write this:
return phoneNumbers.getOrDefault(userId, "Unknown phone number");
Don't write:
Map<Course, List<Student>> participants;
void enrollStudent(Student student) {
List<Student> participating = participants.get(econ101);
if (participating == null) {
participating = new ArrayList<Student>();
participants.put(econ101, participating);
}
participating.add(student);
}
instead write:
Map<Course, List<Student>> participants;
void enrollStudent(Student student) {
participants.computeIfAbsent(econ101,
k -> new ArrayList<Student>())
.add(student);
}
and, crucially, if you are writing APIs, ensure things like getOrDefault, computeIfAbsent, etc. are available so that the users of your API don't have to deal with null nearly as much.

You can write a static test() method like this:
static <T> boolean test(T object, Predicate<T> validation) {
return object != null && validation.test(object);
}
and
static class Foo {
public boolean isValid() {
return true;
}
}
static Foo dosomething() {
return new Foo();
}
public static void main(String[] args) {
Foo a = dosomething();
if (test(a, Foo::isValid))
System.out.println("OK");
else
System.out.println("NG");
}
output:
OK
If dosomething() returns null, it prints NG

Not exactly, but take a look at Optional:
Optional.ofNullable(dosomething())
.filter(Foo::isValid)
.ifPresent(a -> ...);

Related

Why is "new String();" a statement but "new int[0];" not?

I just randomly tried seeing if new String(); would compile and it did (because according to Oracle's Java documentation on "Expressions, Statements, and Blocks", one of the valid statement types is "object creation"),
However, new int[0]; is giving me a "not a statement" error.
What's wrong with this? Aren't I creating an array object with new int[0]?
EDIT:
To clarify this question, the following code:
class Test {
void foo() {
new int[0];
new String();
}
}
causes a compiler error on new int[0];, whereas new String(); on its own is fine. Why is one not acceptable and the other one is fine?
The reason is a somewhat overengineered spec.
The idea behind expressions not being valid statements is that they accomplish nothing whatsoever. 5 + 2; does nothing on its own. You must assign it to something, or pass it to something, otherwise why write it?
There are exceptions, however: Expressions which, on their own, will (or possibly will) have side effects. For example, whilst this is illegal:
void foo(int a) {
a + 1;
}
This is not:
void foo(int a) {
a++;
}
That is because, on its own, a++ is not completely useless, it actually changes things (a is modified by doing this). Effectively, 'ignoring the value' (you do nothing with a + 1 in that first snippet) is acceptable if the act of producing the value on its own causes other stuff to happen: After all, maybe that is what you were after all along.
For that reason, invoking methods is also a legit expressionstatement, and in fact it is quite common that you invoke methods (even ones that don't return void), ignoring the return value. For void methods it's the only legal way to invoke them, even.
Constructors are technically methods and can have side effects. It is extremely unlikely, and quite bad code style, if this method:
void doStuff() {
new Something();
}
is 'sensible' code, but it could in theory be written, bad as it may be: The constructor of the Something class may do something useful and perhaps that's all you want to do here: Make that constructor run, do the useful thing, and then take the created object and immediately toss it in the garbage. Weird, but, okay. You're the programmer.
Contrast with:
new Something[10];
This is different: The compiler knows what the array 'constructor' does. And what it does is nothing useful - it creates an object and returns a reference to the object, and that is all that happens. If you then instantly toss the reference in the garbage, then the entire operation was a complete waste of time, and surely you did not intend to do nothing useful with such a bizarre statement, so the compiler designers thought it best to just straight up disallow you from writing it.
This 'oh dear that code makes no sense therefore I shall not compile it' is very limited and mostly an obsolete aspect of the original compiler spec; it's never been updated and this is not a good way to trust that code is sensible; there's all sorts of linter tools out there that go vastly further in finding you code that just cannot be right, so if you care about that sort of thing, invest in learning those.
Nevertheless, the java 1.0 spec had this stuff baked in and there is no particularly good reason to drop this aspect of the java spec, therefore, it remains, and constructing a new array is not a valid ExpressionStatement.
As JLS §14.8 states, specifically, a ClassInstanceCreationExpression is in the list of valid expressionstatements. Click that word to link to the definition of ClassInstanceCreationExpression and you'll find that it specifically refers to invoking constructors, and not to array construction.
Thus, the JLS is specific and requires this behaviour. javac is simply following the spec.

Optional.get() versus overloaded Optional.orElseThrow()

How can one avoid explicitly throwing an Exception while trying to get the value from an Optional or while making use of Optional.get?
Currently, this is possibly safeguarded with the API orElseThrow as :
// exception could be replaced with any other
Integer opt = anyOddInStream.orElseThrow(
() -> new NoSuchElementException("No value present"));
and yet the directly implementing the get disappoints(when one might not be willing to explicitly throw an exception) while trying to access something like
// the following not only just fails but throws an exception as well
Integer previous = anyOddInStream.get();
What if one wants to make sure that the Optional either has a value and if it doesn't they wouldn't want to continue propagating null ahead?
Java 8 was a huge improvement to the platform, but one of the few mistakes we made was the naming of Optional.get(), because the name just invites people to call it without calling isPresent(), undermining the whole point of using Optional in the first place. (If this was the worst mistake we made in such a big release, then we did pretty well.)
During the Java 9 time frame, we proposed to deprecate Optional.get(), but the public response to that was ... let's say cold. As a smaller step, we introduced orElseThrow() in 10 (see https://bugs.openjdk.java.net/browse/JDK-8140281) as a more transparently named synonym for the current pernicious behavior of get(). IDEs warn on unconditional use of get(), but not on orElseThrow(), which is a step forward in teaching people to code better. The question is, in a sense, a "glass half empty" view of the current situation; get() is still problematic.
We'd love to improve the situation further in future version, but it will probably take some time to bring more of the community around.
From my point of view, Optional.get() is the code smell. Very often combined with Optional.isPresent(), it completely defeats the purpose and the idea of Optional.get(). Here's a more complete reasoning and discussion:
http://royvanrijn.com/blog/2016/04/deprecating-optional-get/
So simply don't use Optional.get(). If you want to return null for the absent value, call Optional.orElse(null).
An alternate method to get value of an optional instead of Optional.get (which more likely than not fails to keep up with user's expectations) is to replace it with a more verbose API introduced in JDK10 termed as Optional.orElseThrow(). In author's words -
Optional.get() is an "attractive nuisance" and is too tempting for
programmers, leading to frequent errors. People don't expect a getter
to throw an exception. A replacement API for Optional.get() with
equivalent semantics should be added.
Optional<Integer> anyOddInStream = Stream.of(2, 4, 6, 8)
.filter(x -> x % 2 == 1)
.findAny();
// one could be well aware of the possible exception handling while reading this
var current = anyOddInStream.orElseThrow();
Note :- The underlying implementation of both these APIs is same, yet the latter reads out more clearly that a NoSuchElementException would be thrown by default if the value is not present which inlines to the existing Optional.orElseThrow(Supplier<? extends X> exceptionSupplier) implementation used by consumers as an explicit alternative.

Compare constant equals object or object equal constant

Follow Java best-java-coding-practices.htm, they say we need call .equals on known string constants rather than UNKNOWN variable
String string = new Test().getString();
// always compare like this, this will never throw NPE
System.out.println("CONSTANT.equals(string):"+CONSTANT.equals(string));
System.out.println("Comparision like string.equals(CONSTANT) may throw NullPointerException");
// next statement will throw NPE
System.out.println("string.equals(CONSTANT):"+string.equals(CONSTANT));
So how about KNOWN variable? Should we still use this way or not?
For example, if I receive an object from server and server notify that this object never null.
In case I want to compare this object with a constant
// CONS: it may return NPE if server return null (for example server do wrong) => app crash
// PRO: when we read this code, we have a mindset that object never null, if it null it is the server bug
object.equals(CONSTANT)
// CONS: When we read this code, we never know why and when object == null so it confusing.
// It not return NPE so code still running and we may have some problem with UI or logic
// PRO: it never return NPE
CONSTANT.equals(object)
Any suggestions would be much appreciated. For me, I prefer object.equals(CONSTANT) for known variable but my team not.
UPDATE I think
CONSTANT.equals(object)
similar too
try{
object.equals(CONSTANT)
catch(NullPointerException ex){
// don't handle or explain anything
}
The practice of reversing the terms around the equality operator when one of the terms is a constant is called a Yoda conditional. You might encounter it in the following forms:
if( constant == variable ) instead of if ( variable == constant )
if( constant.equals( variable ) ) instead of if( variable.equals( constant ) )
Do not use Yoda conditionals. The Principle of Least Surprise is not just violated by this construct, it is gang-raped.
Also, this is a form of "defensive programming". Do not engage in defensive programming; engage in offensive programming instead. Read Trevor Jim's post Postel's law is not for you.
Also, do not blindly follow some advice just because someone calls it a "best practice". Who says it is a best practice?
Is it just a couple of folks out there? then by definition, they are not entitled to dress their subjective opinion with an objective title like "best practice".
Is it the majority of the industry? The majority is usually wrong. (Some might even say always wrong, watch Paul Rulkens # TEDxMaastricht 2014)
Is it virtually everyone in the industry? Then clearly, the industry is engaging in groupthink.
Here are the reasons often cited for using Yoda conditionals, and their rebuttals:
Alleged reason #1
Statement: It will catch accidental use of the assignment operator where the equality operator was intended.
Rebuttal: Such accidental use should be impossible because your compiler or your IDE should be issuing a warning if you try to do this. If you are not receiving a warning, then you have other, much bigger problems in need of solving, i.e. using the wrong programming language, using the wrong IDE, or trying to write code without first having figured out how to enable all warnings.
Alleged reason #2
Statement: It works even if the variable accidentally happens to be null.
Rebuttal: No, it does not work; it silently fails. If you follow offensive programming, the definition of "it works" is that it must produce correct results when given valid input, and it must deliberately fail when given invalid input. So, there are two possibilities: either the variable may legitimately be null, or it may not.
if the variable may legitimately be null, then explicitly check against null.
if the variable may not be null, then write the code so that it will not fail to fail in the event that the variable is in fact null.

Alternatives to returning NULL

/**
* Returns the foo with the matching id in this list
*
* #param id the id of the foo to return
* #return the foo with the matching id in this list
*/
public Foo getFoo(int id)
{
for (Foo foo : list)
{
if (foo.getID() == id)
{
return foo;
}
}
return null;
}
Instead of returning null when foo is not found, should I throw an exception? Does it matter, and is there a "best practices" idiom on the subject? By the way, I know my example is a bit contrived, but I hope you get the idea...
Thanks.
EDIT
Changed code to get Foo based on id to better illustrate a real-world scenario.
Returning null is not only more simple to handle, performs better too. The exceptions must be used to handle exceptional cases.
I'd say it depends on the semantics of your method.
Will foo be almost always found in the list? (for example, if it is a cache that holds a finite amount of objects). If so, then not being found might mean something has gone wrong -- some app initialization failed, for example, or the key is invalid -- and an exception might be justifiable.
In most circumstances, however, I'd return null. Maybe the client knows the object might not be there and has coded logic to handle that case; if you used an exception, that code would be much harder to read, understand, and maintain.
Some APIs actually provide two methods: a find method that may return null, and a get or load method that throws an exception.
Hmmm... when in doubt, err in favor of null :)
Returning null is fine, if it is documented as a valid result.
Another option is the null-object pattern. That is - an instance of Foo that doesn't have any data:
public class Foo {
public static final Foo NULL_FOO = new Foo();
}
and return it instead.
I prefer returning null. This is a perfectly fine result to return from a method, and your code that calls the method should handle null values appropriately. That might mean throwing an exception in your calling code, but I wouldn't do it in this method.
This way, if someone else wants to call your method down the line, they can handle null values differently than you if they choose. If you threw and exception it could potentially force another programmer to alter their code in a way different than what they intended.
Of course, there are some cases where it would make sense to throw an exception if something is null (like, a connection object or something like that, that you actually need to have a value and if you don't then that means something is wrong). But, as a rule of thumb, you should be fine returning null in most cases.
It's best to avoid exceptions if you can, but sometimes you just can't. In this case, what if you had stored null in the list? You can't tell the difference between 'found null' and 'could not find what you wanted'.
There is a pattern, it's called Option Types and it's used a lot in Scala. You either return a container with the item, or a container of a class that says 'I'm empty'. The wiki article will give a better picture.
You could also have a 'does this exist in the collection?' method which returns a bool, then throw an exception from the above code for if you didn't check first.
And just a comment completely unrelated to your actual question. If you implement equals, it should only return true if the two objects are actually considered equal. Therefore the above code must always return the object you pass into it!
Best pactice would be to say in the Javadoc that null is return when no match is found.
Another approach might be to return a List of matches which could be empty (and could have more than one) However I don't like this approach.
Another approach might be to return a NULL_FOO of type Foo value.
I would prefer to just return null.
One way around this is to look at what are you going to do with the value and enrich the function so that the returned value is used in the method and not returned. e.g. if you are going to call a method with the value, just call it in the function which avoids the need to return anything.
This is an old question but I didn't find guava's Optional class mentioned here and also JDK's Optional (from Java 8) which serves the same purpose and has more functionality.
This article is a good overview on the reasons for using guava's Optional. I highly recommend reading it.
Here's an excerpt:
What's the point?
Besides the increase in readability that comes from giving null a
name, the biggest advantage of Optional is its idiot-proof-ness. It
forces you to actively think about the absent case if you want your
program to compile at all, since you have to actively unwrap the
Optional and address that case. Null makes it disturbingly easy to
simply forget things, and though FindBugs helps, we don't think it
addresses the issue nearly as well.
This is especially relevant when you're returning values that may or
may not be "present." You (and others) are far more likely to forget
that other.method(a, b) could return a null value than you're likely
to forget that a could be null when you're implementing other.method.
Returning Optional makes it impossible for callers to forget that
case, since they have to unwrap the object themselves for their code
to compile.
My personal opinion, if that matters at all, is that returning null is not so terrible in an already verbose language like Java. The signature of the method sometimes screams that there can be some sort of null kind of result and using Optional doesn't add anything in terms of semantics anyway. For example:
public Point2D intersect(Line line)
Or in a method that looks up a value in a map by key.
If one calls such a method and performs a null check on the result, it's pretty obvious what is going on (checking for parallel lines or key not found). I would favor returning null lest I bloat my code.
I would always document it in the javadoc though.
majory it depends on the scenarios. If your app is itself producer and consumer of this method then it is completly upto you to decide what to do, Else you need to decide based on usage of the method and Client needs.
Returning null is perfectly acceptable. I would go the extra couple dozen keystrokes and document the possibility of returning null in the JavaDoc.
Throwing checked exception means you have to try/catch or re-throw that exception everywhere your method gets called. An unchecked exception, especially anything other than an NPE, is going to catch people by surprise.
In this case, since you're defining an accessor, it should return null. If it were another method where this method should guarantee a non-null response, an exception would be more appropriate.
As a side note though, rather than calling the sample method a getter it might be more appropriate to name it something like Foo findFoo(Foo f) since you're searching rather than just getting.
I think it's a matter of taste and in this case it also depends on if the list may contain null values. If the list may contain null values, null would also be a valid method argument and you would need to distinguish between returning null (e.g. null was passed, found and returned) or telling the method caller that the passed null value was not found.
This might not answer your question directly but it comes from a few remarks I've gotten from Stackoverflow members on similar topics.
Instead of returning null when foo is not found, should I throw an exception? Does it matter, and is there a "best practices" idiom on the subject? By the way, I know my example is a bit contrived, but I hope you get the idea..."
From what I gather, Exceptions should be thrown from a method when the Exception concerns a parameter given to the method. For example, a method accepting File instances would throw a NullPointerException or an IOException. This is following the idea that there's a contract between the caller and callee that the caller should sent valid objects and take care of them if they're invalid.
Also, you need to decide whether to handle pre- and postconditions. You can place a guard at the beginning of a method to handle parameters and this would save quite a bit of code. However, some view this as an incorrect approach in that some validation, say in a UI, should be done beforehand.
To finish off, it's perfectly valid to return a null object if the intent is to retrieve a a single instance. This is to paraphrase that an object was not found or doesn't exist. When it comes to groups of objects I think the convention is simply to return an empty Collection/List.
I'd say it depends on your app and how the method will be used.
If you expect a "not found" result happen frequently enough that it could negatively affect performance*, then return null, and check for it in the caller.
If "not found" results will be relatively rare or will cause you app give up on the request, then throwing an exception would be fine. Exceptions could make your code easier to read, as you can then guarantee a successful return will produce an object, so you don't have to null-check it.
I subscribe to the opinion that exceptions should be used for exceptional conditions, which is a superset of error conditions. I also have adopted Spring/Hibernate's preference for unchecked exceptions, which avoids burdensome try/catch logic.
* There is not much performance overhead from using exceptions vs. returning null. I just did a quick test, it takes 4ms to call a method a million times that returns null, and only 535ms to another method million times that throws an exception.
Another point of view I haven't read in the other answers is the following:
Does the list contain null's of Foo? If this is the case, one would not know whether the id was found, or whether it was associated with null. In this case:
Throw an exception that the list is not found;
Wrap the result in another object (e.g. a SearchResult, which tells you if the object was found, it's associative id, it's result, or no result if it was not found);
Create the method existsFoo(int id).
Each solution has it's own problems, and it depends on the case which to use:
As others noted, Exceptions are exceptional;
A wrapper, SearchResult, has to be allocated each time you'd like to retry a search. The wrapper can be made mutable, but this introduces a lot of new difficulties and problems;
existsFoo has to search the list which doubles the cost of knowing whether the key exists or not.
Generally I can say:
Is an ID not being found exceptional? Use IllegalArgumentException;
Is the result passed to other classes, used as an object? Use a wrapper, e.g. SearchResult;
Is with getFoo only checked whether it's null or not (it exists or not)? Use another method, existsFoo.
While I agree that coding for null is simple and easy boilerplate programmer conditioning, it adds little value for the complexity introduced. Always assuming non-null references makes for cleaner logic with slightly less code -- you still have to test for failure.
The annotation excerpt below will help you to not fall into the old ways...
Use #Nullable
To eliminate NullPointerExceptions in your codebase, you must be
disciplined about null references. We've been successful at this by
following and enforcing a simple rule:
Every parameter is non-null unless explicitly specified.
The Guava: Google Core Libraries for Java and JSR-305 have simple APIs
to get a nulls under control. Preconditions.checkNotNull can be used
to fast-fail if a null reference is found, and #Nullable can be used
to annotate a parameter that permits the null value:
import static com.google.common.base.Preconditions.checkNotNull;
import static javax.annotation.Nullable;
public class Person {
...
public Person(String firstName, String lastName, #Nullable Phone phone) {
this.firstName = checkNotNull(firstName, "firstName");
this.lastName = checkNotNull(lastName, "lastName");
this.phone = phone;
}
If null is permissible by your class, you can annotate the field or
parameter with #Nullable ... using any #Nullable annotation, like
edu.umd.cs.findbugs.annotations.Nullable or javax.annotation.Nullable.

What is the point of the class Option[T]?

I am not able to understand the point of Option[T] class in Scala. I mean, I am not able to see any advanages of None over null.
For example, consider the code:
object Main{
class Person(name: String, var age: int){
def display = println(name+" "+age)
}
def getPerson1: Person = {
// returns a Person instance or null
}
def getPerson2: Option[Person] = {
// returns either Some[Person] or None
}
def main(argv: Array[String]): Unit = {
val p = getPerson1
if (p!=null) p.display
getPerson2 match{
case Some(person) => person.display
case None => /* Do nothing */
}
}
}
Now suppose, the method getPerson1 returns null, then the call made to display on first line of main is bound to fail with NPE. Similarly if getPerson2 returns None, the display call will again fail with some similar error.
If so, then why does Scala complicate things by introducing a new value wrapper (Option[T]) instead of following a simple approach used in Java?
UPDATE:
I have edited my code as per #Mitch's suggestion. I am still not able to see any particular advantage of Option[T]. I have to test for the exceptional null or None in both cases. :(
If I have understood correctly from #Michael's reply, is the only advantage of Option[T] is that it explicitly tells the programmer that this method could return None? Is this the only reason behind this design choice?
You'll get the point of Option better if you force yourself to never, ever, use get. That's because get is the equivalent of "ok, send me back to null-land".
So, take that example of yours. How would you call display without using get? Here are some alternatives:
getPerson2 foreach (_.display)
for (person <- getPerson2) person.display
getPerson2 match {
case Some(person) => person.display
case _ =>
}
getPerson2.getOrElse(Person("Unknown", 0)).display
None of this alternatives will let you call display on something that does not exist.
As for why get exists, Scala doesn't tell you how your code should be written. It may gently prod you, but if you want to fall back to no safety net, it's your choice.
You nailed it here:
is the only advantage of Option[T] is
that it explicitly tells the
programmer that this method could
return None?
Except for the "only". But let me restate that in another way: the main advantage of Option[T] over T is type safety. It ensures you won't be sending a T method to an object that may not exist, as the compiler won't let you.
You said you have to test for nullability in both cases, but if you forget -- or don't know -- you have to check for null, will the compiler tell you? Or will your users?
Of course, because of its interoperability with Java, Scala allows nulls just as Java does. So if you use Java libraries, if you use badly written Scala libraries, or if you use badly written personal Scala libraries, you'll still have to deal with null pointers.
Other two important advantages of Option I can think of are:
Documentation: a method type signature will tell you whether an object is always returned or not.
Monadic composability.
The latter one takes much longer to fully appreciate, and it's not well suited to simple examples, as it only shows its strength on complex code. So, I'll give an example below, but I'm well aware it will hardly mean anything except for the people who get it already.
for {
person <- getUsers
email <- person.getEmail // Assuming getEmail returns Option[String]
} yield (person, email)
Compare:
val p = getPerson1 // a potentially null Person
val favouriteColour = if (p == null) p.favouriteColour else null
with:
val p = getPerson2 // an Option[Person]
val favouriteColour = p.map(_.favouriteColour)
The monadic property bind, which appears in Scala as the map function, allows us to chain operations on objects without worrying about whether they are 'null' or not.
Take this simple example a little further. Say we wanted to find all the favourite colours of a list of people.
// list of (potentially null) Persons
for (person <- listOfPeople) yield if (person == null) null else person.favouriteColour
// list of Options[Person]
listOfPeople.map(_.map(_.favouriteColour))
listOfPeople.flatMap(_.map(_.favouriteColour)) // discards all None's
Or perhaps we would like to find the name of a person's father's mother's sister:
// with potential nulls
val father = if (person == null) null else person.father
val mother = if (father == null) null else father.mother
val sister = if (mother == null) null else mother.sister
// with options
val fathersMothersSister = getPerson2.flatMap(_.father).flatMap(_.mother).flatMap(_.sister)
I hope this sheds some light on how options can make life a little easier.
The difference is subtle. Keep in mind to be truly a function it must return a value - null is not really considered to be a "normal return value" in that sense, more a bottom type/nothing.
But, in a practical sense, when you call a function that optionally returns something, you would do:
getPerson2 match {
case Some(person) => //handle a person
case None => //handle nothing
}
Granted, you can do something similar with null - but this makes the semantics of calling getPerson2 obvious by virtue of the fact it returns Option[Person] (a nice practical thing, other than relying on someone reading the doc and getting an NPE because they don't read the doc).
I will try and dig up a functional programmer who can give a stricter answer than I can.
For me options are really interesting when handled with for comprehension syntax. Taking synesso preceding example:
// with potential nulls
val father = if (person == null) null else person.father
val mother = if (father == null) null else father.mother
val sister = if (mother == null) null else mother.sister
// with options
val fathersMothersSister = for {
father <- person.father
mother <- father.mother
sister <- mother.sister
} yield sister
If any of the assignation are None, the fathersMothersSister will be None but no NullPointerException will be raised. You can then safely pass fathersMothersSisterto a function taking Option parameters without worrying. so you don't check for null and you don't care of exceptions. Compare this to the java version presented in synesso example.
You have pretty powerful composition capabilities with Option:
def getURL : Option[URL]
def getDefaultURL : Option[URL]
val (host,port) = (getURL orElse getDefaultURL).map( url => (url.getHost,url.getPort) ).getOrElse( throw new IllegalStateException("No URL defined") )
Maybe someone else pointed this out, but I didn't see it:
One advantage of pattern-matching with Option[T] vs. null checking is that Option is a sealed class, so the Scala compiler will issue a warning if you neglect to code either the Some or the None case. There is a compiler flag to the compiler that will turn warnings into errors. So it's possible to prevent the failure to handle the "doesn't exist" case at compile time rather than at runtime. This is an enormous advantage over the use of the null value.
It's not there to help avoid a null check, it's there to force a null check. The point becomes clear when your class has 10 fields, two of which could be null. And your system has 50 other similar classes. In the Java world, you try to prevent NPEs on those fields using some combination of mental horesepower, naming convention, or maybe even annotations. And every Java dev fails at this to a significant degree. The Option class not only makes "nullable" values visually clear to any developers trying to understand the code, but allows the compiler to enforce this previously unspoken contract.
[ copied from this comment by Daniel Spiewak ]
If the only way to use Option were
to pattern match in order to get
values out, then yes, I agree that it
doesn’t improve at all over null.
However, you’re missing a *huge* class
of its functionality. The only
compelling reason to use Option is
if you’re using its higher-order
utility functions. Effectively, you
need to be using its monadic nature.
For example (assuming a certain amount
of API trimming):
val row: Option[Row] = database fetchRowById 42
val key: Option[String] = row flatMap { _ get “port_key” }
val value: Option[MyType] = key flatMap (myMap get)
val result: MyType = value getOrElse defaultValue
There, wasn’t that nifty? We can
actually do a lot better if we use
for-comprehensions:
val value = for {
row <- database fetchRowById 42
key <- row get "port_key"
value <- myMap get key
} yield value
val result = value getOrElse defaultValue
You’ll notice that we are *never*
checking explicitly for null, None or
any of its ilk. The whole point of
Option is to avoid any of that
checking. You just string computations
along and move down the line until you
*really* need to get a value out. At
that point, you can decide whether or
not you want to do explicit checking
(which you should never have to do),
provide a default value, throw an
exception, etc.
I never, ever do any explicit matching
against Option, and I know a lot of
other Scala developers who are in the
same boat. David Pollak mentioned to
me just the other day that he uses
such explicit matching on Option (or
Box, in the case of Lift) as a sign
that the developer who wrote the code
doesn’t fully understand the language
and its standard library.
I don’t mean to be a troll hammer, but
you really need to look at how
language features are *actually* used
in practice before you bash them as
useless. I absolutely agree that
Option is quite uncompelling as *you*
used it, but you’re not using it the
way it was designed.
One point that nobody else here seems to have raised is that while you can have a null reference, there is a distinction introduced by Option.
That is you can have Option[Option[A]], which would be inhabited by None, Some(None) and Some(Some(a)) where a is one of the usual inhabitants of A. This means that if you have some kind of container, and want to be able to store null pointers in it, and get them out, you need to pass back some extra boolean value to know if you actually got a value out. Warts like this abound in the java containers APIs and some lock-free variants can't even provide them.
null is a one-off construction, it doesn't compose with itself, it is only available for reference types, and it forces you to reason in a non-total fashion.
For instance, when you check
if (x == null) ...
else x.foo()
you have to carry around in your head throughout the else branch that x != null and that this has already been checked. However, when using something like option
x match {
case None => ...
case Some(y) => y.foo
}
you know y is not Noneby construction -- and you'd know it wasn't null either, if it weren't for Hoare's billion dollar mistake.
Option[T] is a monad, which is really useful when you using high-order functions to manipulate values.
I'll suggest you read articles listed below, they are really good articles that show you why Option[T] is useful and how can it be used in functional way.
Martians vs Monads: Null Considered Harmful
Monads are Elephants Part 1
Adding on to Randall's teaser of an answer, understanding why the potential absence of a value is represented by Option requires understanding what Option shares with many other types in Scala—specifically, types modeling monads. If one represents the absence of a value with null, that absence-presence distinction can't participate in the contracts shared by the other monadic types.
If you don't know what monads are, or if you don't notice how they're represented in Scala's library, you won't see what Option plays along with, and you can't see what you're missing out on. There are many benefits to using Option instead of null that would be noteworthy even in the absence of any monad concept (I discuss some of them in the "Cost of Option / Some vs null" scala-user mailing list thread here), but talking about it isolation is kind of like talking about a particular linked list implementation's iterator type, wondering why it's necessary, all the while missing out on the more general container/iterator/algorithm interface. There's a broader interface at work here too, and Option provides a presence-and-absence model of that interface.
I think the key is found in Synesso's answer: Option is not primarily useful as a cumbersome alias for null, but as a full-fledged object that can then help you out with your logic.
The problem with null is that it is the lack of an object. It has no methods that might help you deal with it (though as a language designer you can add increasingly long lists of features to your language that emulate an object if you really feel like it).
One thing Option can do, as you've demonstrated, is to emulate null; you then have to test for the extraordinary value "None" instead of the extraordinary value "null". If you forget, in either case, bad things will happen. Option does make it less likely to happen by accident, since you have to type "get" (which should remind you that it might be null, er, I mean None), but this is a small benefit in exchange for an extra wrapper object.
Where Option really starts to show its power is helping you deal with the concept of I-wanted-something-but-I-don't-actually-have-one.
Let's consider some things you might want to do with things that might be null.
Maybe you want to set a default value if you have a null. Let's compare Java and Scala:
String s = (input==null) ? "(undefined)" : input;
val s = input getOrElse "(undefined)"
In place of a somewhat cumbersome ?: construct we have a method that deals with the idea of "use a default value if I'm null". This cleans up your code a little bit.
Maybe you want to create a new object only if you have a real value. Compare:
File f = (filename==null) ? null : new File(filename);
val f = filename map (new File(_))
Scala is slightly shorter and again avoids sources of error. Then consider the cumulative benefit when you need to chain things together as shown in the examples by Synesso, Daniel, and paradigmatic.
It isn't a vast improvement, but if you add everything up, it's well worth it everywhere save very high-performance code (where you want to avoid even the tiny overhead of creating the Some(x) wrapper object).
The match usage isn't really that helpful on its own except as a device to alert you about the null/None case. When it is really helpful is when you start chaining it, e.g., if you have a list of options:
val a = List(Some("Hi"),None,Some("Bye"));
a match {
case List(Some(x),_*) => println("We started with " + x)
case _ => println("Nothing to start with.")
}
Now you get to fold the None cases and the List-is-empty cases all together in one handy statement that pulls out exactly the value you want.
Null return values are only present for compatibility with Java. You should not use them otherwise.
It is really a programming style question. Using Functional Java, or by writing your own helper methods, you could have your Option functionality but not abandon the Java language:
http://functionaljava.org/examples/#Option.bind
Just because Scala includes it by default doesn't make it special. Most aspects of functional languages are available in that library and it can coexist nicely with other Java code. Just as you can choose to program Scala with nulls you can choose to program Java without them.
Admitting in advance that it is a glib answer, Option is a monad.
Actually I share the doubt with you. About Option it really bothers me that 1) there is a performance overhead, as there is a lor of "Some" wrappers created everywehre. 2) I have to use a lot of Some and Option in my code.
So to see advantages and disadvantages of this language design decision we should take into consideration alternatives. As Java just ignores the problem of nullability, it's not an alternative. The actual alternative provides Fantom programming language. There are nullable and non-nullable types there and ?. ?: operators instead of Scala's map/flatMap/getOrElse. I see the following bullets in the comparison:
Option's advantage:
simpler language - no additional language constructs required
uniform with other monadic types
Nullable's advantage:
shorter syntax in typical cases
better performance (as you don't need to create new Option objects and lambdas for map, flatMap)
So there is no obvious winner here. And one more note. There is no principal syntactic advantage for using Option. You can define something like:
def nullableMap[T](value: T, f: T => T) = if (value == null) null else f(value)
Or use some implicit conversions to get pritty syntax with dots.
The real advantage of having explicit option types is that you are able to not use them in 98% of all places, and thus statically preclude null exceptions. (And in the other 2% the type system reminds you to check properly when you actually access them.)
Another situation where Option works, is in situations where types are not able to have a null value. It is not possible to store null in an Int, Float, Double, etc. value, but with an Option you can use the None.
In Java, you would need to use the boxed versions (Integer, ...) of those types.

Categories