java.util.Optional: a better implementation?

nicarran at gmail.com nicarran at gmail.com
Wed Oct 29 12:06:18 UTC 2014


Hi,

I'm evaluating java.util.Optional to use it all around my code. I
noticed that its current implementation checks for null on almost every
method and that these checks can be avoided by changing its
implementation to an abstract Optional class with two subclasses, one
for the EMPTY and another for the not-empty (present) values without
breaking compatibility. Something like this:

**********************

public abstract class Optional<T> {

    private static final Optional<?> EMPTY=new Empty<>();

    private static class Empty<T>
        extends Optional<T> {

        @Override
        public boolean isPresent() {
            return false;
        }
        @Override
        public T get() {
            throw new NoSuchElementException("No value present");
        }
        @Override
        public void ifPresent(Consumer<? super T> consumer) {
        }
        // and so on
    }

    private static class Present<T>
        extends Optional<T> {

        private final T value;

        Present(T value) {
            this.value=Objects.requireNonNull(value);
        }

        @Override
        public boolean isPresent() {
            return true;
        }
        @Override
        public T get() {
            return value;
        }
        @Override
        public void ifPresent(Consumer<? super T> consumer) {
            consumer.accept(value);
        }
        // and so on
    }

    private Optional() {}

    public static <T> Optional<T> of(T value) {
        return new Present<>(value);
    }

    public static <T> Optional<T> ofNullable(T value) {
        return value==null? empty(): new Present<>(value);
    }
    
    @SuppressWarnings("unchecked")
    public static <T> Optional<T> empty(){
        return (Optional<T>)EMPTY;
    }

    public abstract boolean isPresent();

    public abstract T get();

    public abstract void ifPresent(Consumer<? super T> consumer);

    // and so on
}
********************

The JVM probably optimizes and throws away the null checks yielding in
equal performance compared to the proposed implementation (above) ---I
haven't done any performance tests----, but why wait for the JVM when
this implementation is also nicer to read? What do you think?

Please let me know if this is not the appropriate mailing list to post
this message,
Thanks,
Nicolas



More information about the discuss mailing list