skiwi
skiwi

Reputation: 69379

Why is Optional<T> declared as a final class?

I was playing with the following question: Using Java 8's Optional with Stream::flatMap and wanted to add a method to a custom Optional<T> and then check if it worked.
More precise, I wanted to add a stream() to my CustomOptional<T> that returns an empty stream if no value is present, or a stream with a single element if it is present.

However, I came to the conclusion that Optional<T> is declared as final.

Why is this so? There are loads of classes that are not declared as final, and I personally do not see a reason here to declare Optional<T> final.

As a second question, why can not all methods be final, if the worry is that they would be overridden, and leave the class non-final?

Upvotes: 17

Views: 5448

Answers (4)

Prakash Ayappan
Prakash Ayappan

Reputation: 455

Though we could not extend the Optional class, we could create our own wrapper class.

public final class Opt {

    private Opt() {

    }

    public static final <T> Stream<T> filledOrEmpty(T t) {

        return Optional.ofNullable(t).isPresent() ? Stream.of(t) : Stream.empty();

    }

}

Hope it might helps you. Glad to see the reaction!

Upvotes: 1

Aniket Thakur
Aniket Thakur

Reputation: 68985

As others have stated Optional is a value based class and since it is a value based class it should be immutable which needs it to be final.

But we missed the point for this. One of the main reason why value based classes are immutable is to guarantee thread safety. Making it immutable makes it thread safe. Take for eg String or primitive wrappers like Integer or Float. They are declared final for similar reasons.

Upvotes: 3

SharpKnight
SharpKnight

Reputation: 455

According to this page of the Java SE 8 API docs, Optional<T> is a value based class. According to this page of the API docs, value-based classes have to be immutable.

Declaring all the methods in Optional<T> as final will prevent the methods from being overridden, but that will not prevent an extending class from adding fields and methods. Extending the class and adding a field together with a method that changes the value of that field would make that subclass mutable and hence would allow the creation of a mutable Optional<T>. The following is an example of such a subclass that could be created if Optional<T> would not be declared final.

//Example created by @assylias
public class Sub<T> extends Optional<T> {
    private T t;

    public void set(T t) {
        this.t = t;
    }
}

Declaring Optional<T> final prevents the creation of subclasses like the one above and hence guarantees Optional<T> to be always immutable.

Upvotes: 18

Dolda2000
Dolda2000

Reputation: 25855

Probably, the reason is the same as why String is final; that is, so that all users of the Optional class can be assured that the methods on the instance they receive keep to their contract of always returning the same value.

Upvotes: 1

Related Questions