Optional require(s) NonNull

Alessio Stalla alessiostalla at gmail.com
Tue Oct 30 08:52:37 PDT 2012


On Tue, Oct 30, 2012 at 4:36 PM, Roland Tepp <luolong at gmail.com> wrote:
> 2012/10/30 Alessio Stalla <alessiostalla at gmail.com>
>>
>> On Tue, Oct 30, 2012 at 4:02 PM, Roland Tepp <luolong at gmail.com> wrote:
>> > 2012/10/30 Brian Goetz <brian.goetz at oracle.com>
>> > The danger of having a get() method directly on Optional is that this
>> > encourages the direct use of optional.get() which is susceptible to
>> > NoSuchElementException with the same casualty as NullPointerException's
>> > are
>> > common without use of Optional.
>>
>> There is a big difference: with get(), the exception occurs at the
>> exact location where you call get(), i.e. as soon as you need to pass
>> your Optional value to some method that expects non-optional values.
>> The problem with NPEs is not that they are thrown, but that they can
>> be thrown far away from the code that actually caused them.
>>
>>
>
>
> No, not really.
>
> NPE happens whenever you are trying to use (actually dereference) an object
> that is null.
> Same is with optional. You get the NSEE when you try to use the value that
> is not there.
> It might be slightly earlier than with nullable objects, but effectively the
> result is same.

But Optional is explicit, while "nullable" is not: you can only
propagate an Optional value through code that expects an Optional, and
as soon as you step out of that assumption, you need to handle it
somehow, perhaps by calling get(). Instead, you can propagate a null
reference almost everywhere, and it might not get caught until someone
tries to dereference it. In other words, get() only gets called at the
boundary between code that expects optional values and code that does
not, while a null reference can be accessed from anywhere.

>>
>> > Moving it out of the Optional and into the Some/Present will require
>> > explicit casting of the Optional to Present which at least is more
>> > deliberate action and force the developer to consider this at least for
>> > a
>> > moment.
>> > i.e. something like this:
>> >     Optional<String> optional = ...
>> >     if (optional.isPresent()) {
>> >         ((Present) optional).get().split(...);
>> >     }
>>
>> If you already bothered to guard it with if (optional.isPresent()) why
>> the need for casting? And, if you don't guard it, it will fail with a
>> CCE just as if it would have failed with a NoSuchElementException.
>
>
> Because casting an object is considered dangerous operation without guarding
> the cast.
> That is exactly it - it forces me into thinking about weather the cast is
> safe as opposed exposing a potentially dangerous (as in - it may blow up in
> your face) to user without predudice.

That is a problem of expectations - get() should be considered a
dangerous operation that needs guarding, just like a cast. IDEs can
help in that regard. A lot of operations are unsafe, yet they don't
usually require a cast for that reason alone. To make a silly example,
I doubt you would advocate for

if(y != 0) {
  z = x / (NonZero) y;
}

Alessio
-- 
Some gratuitous spam:

http://ripple-project.org Ripple, social credit system
http://villages.cc Villages.cc, Ripple-powered community economy
http://common-lisp.net/project/armedbear ABCL, Common Lisp on the JVM
http://code.google.com/p/tapulli my current open source projects
http://www.manydesigns.com/ ManyDesigns Portofino, open source
model-driven Java web application framework


More information about the lambda-dev mailing list