2424 */
2525package java .util ;
2626
27+ import org .checkerframework .checker .nullness .qual .PolyNull ;
28+ import org .checkerframework .checker .nullness .qual .Nullable ;
29+ import org .checkerframework .checker .nullness .qual .NonNull ;
2730import org .checkerframework .framework .qual .AnnotatedFor ;
31+ import org .checkerframework .framework .qual .Covariant ;
2832import org .checkerframework .framework .qual .CFComment ;
2933
34+ import org .checkerframework .checker .optional .qual .Present ;
35+ import org .checkerframework .framework .qual .EnsuresQualifierIf ;
36+
3037import java .util .function .Consumer ;
3138import java .util .function .Function ;
3239import java .util .function .Predicate ;
7178"meaning, but are unrelated by the Java type hierarchy." ,
7279"@Covariant makes Optional<@NonNull String> a subtype of Optional<@Nullable String>."
7380})
74- @ AnnotatedFor ({"lock" , "nullness" })
75- public final class Optional <T > {
81+ @ AnnotatedFor ({"lock" , "nullness" , "optional" })
82+ @ Covariant (0 )
83+ public final @ NonNull class Optional <T > {
7684 /**
7785 * Common instance for {@code empty()}.
7886 */
@@ -81,7 +89,7 @@ public final class Optional<T> {
8189 /**
8290 * If non-null, the value; if null, indicates no value is present
8391 */
84- private final T value ;
92+ private final @ Nullable T value ;
8593
8694 /**
8795 * Constructs an empty instance.
@@ -118,7 +126,7 @@ public static<T> Optional<T> empty() {
118126 * @param value the non-{@code null} value to describe
119127 * @throws NullPointerException if value is {@code null}
120128 */
121- private Optional (T value ) {
129+ private Optional (@ NonNull T value ) {
122130 this .value = Objects .requireNonNull (value );
123131 }
124132
@@ -131,7 +139,7 @@ private Optional(T value) {
131139 * @return an {@code Optional} with the value present
132140 * @throws NullPointerException if value is {@code null}
133141 */
134- public static <T > Optional <T > of (T value ) {
142+ public static <T > @ Present Optional <T > of (@ NonNull T value ) {
135143 return new Optional <>(value );
136144 }
137145
@@ -144,7 +152,7 @@ public static <T> Optional<T> of(T value) {
144152 * @return an {@code Optional} with a present value if the specified value
145153 * is non-{@code null}, otherwise an empty {@code Optional}
146154 */
147- public static <T > Optional <T > ofNullable (T value ) {
155+ public static <T > Optional <T > ofNullable (@ Nullable T value ) {
148156 return value == null ? empty () : of (value );
149157 }
150158
@@ -158,7 +166,7 @@ public static <T> Optional<T> ofNullable(T value) {
158166 * @return the non-{@code null} value described by this {@code Optional}
159167 * @throws NoSuchElementException if no value is present
160168 */
161- public T get () {
169+ public @ NonNull T get (@ Present Optional < T > this ) {
162170 if (value == null ) {
163171 throw new NoSuchElementException ("No value present" );
164172 }
@@ -170,6 +178,7 @@ public T get() {
170178 *
171179 * @return {@code true} if a value is present, otherwise {@code false}
172180 */
181+ @ EnsuresQualifierIf (result = true , expression = "this" , qualifier = Present .class )
173182 public boolean isPresent () {
174183 return value != null ;
175184 }
@@ -272,7 +281,7 @@ public Optional<T> filter(Predicate<? super T> predicate) {
272281 * present, otherwise an empty {@code Optional}
273282 * @throws NullPointerException if the mapping function is {@code null}
274283 */
275- public <U > Optional <U > map (Function <? super T , ? extends U > mapper ) {
284+ public <U > Optional <U > map (Function <? super T , ? extends @ Nullable U > mapper ) {
276285 Objects .requireNonNull (mapper );
277286 if (!isPresent ()) {
278287 return empty ();
@@ -366,7 +375,7 @@ public Stream<T> stream() {
366375 * May be {@code null}.
367376 * @return the value, if present, otherwise {@code other}
368377 */
369- public T orElse (T other ) {
378+ public @ PolyNull T orElse (@ PolyNull T other ) {
370379 return value != null ? value : other ;
371380 }
372381
@@ -380,7 +389,7 @@ public T orElse(T other) {
380389 * @throws NullPointerException if no value is present and the supplying
381390 * function is {@code null}
382391 */
383- public T orElseGet (Supplier <? extends T > supplier ) {
392+ public @ PolyNull T orElseGet (Supplier <? extends @ PolyNull T > supplier ) {
384393 return value != null ? value : supplier .get ();
385394 }
386395
@@ -416,7 +425,7 @@ public T orElseThrow() {
416425 * @throws NullPointerException if no value is present and the exception
417426 * supplying function is {@code null}
418427 */
419- public <X extends Throwable > T orElseThrow (Supplier <? extends X > exceptionSupplier ) throws X {
428+ public <X extends Throwable > T orElseThrow (@ Present Optional < T > this , Supplier <? extends X > exceptionSupplier ) throws X {
420429 if (value != null ) {
421430 return value ;
422431 } else {
0 commit comments