8

Is it possible to document that return value is not null with Java Optional?

Most tools and frameworks care only about arguments but I'd like to express in type that return value is not null (instead of doing that in JavaDoc).

UPDATE Looks like you can agree with team to use Optional as return value if you want to express possible null and direct object when it is definitely not null:

public Optional<Job> getJob() {  ... }
public Job extractJob(NonNullJobHolder<Job> holder) { ... }
avs099
  • 10,937
  • 6
  • 60
  • 110
gavenkoa
  • 45,285
  • 19
  • 251
  • 303
  • 7
    If you return Optional, then you should never return null, no need for documentation – Lino Jul 25 '18 at 16:45
  • There is `Optional.of` which forbid `null`. Is there subclass of Optional that itself says container has value? Or it is not possible to use sub-type due to type erasure of generics? – gavenkoa Jul 25 '18 at 16:48
  • Sounds like you need to just... read the Optional documentation and experiment with Optional. You seem to be operating under a couple of pretty serious misconceptions, and the documentation is good enough to sort them out for you. – Nic Jul 25 '18 at 16:50
  • 1
    Returning non-null values should be the normal state of things; it should be implied. It is methods which actually can return null that need to be explicitly documented as doing so. (Whether that should be done with Optional depends on the method and the design; see https://stackoverflow.com/questions/26327957/should-java-8-getters-return-optional-type for an authoritative answer.) – VGR Jul 25 '18 at 19:44

2 Answers2

8

I don't know why you're under the impression that most of them apply only to parameters.

org.eclipse.jdt.annotation.NonNull

@Documented
@Retention(value=CLASS)
@Target(value={FIELD,METHOD,PARAMETER,LOCAL_VARIABLE})
public @interface NonNull

org.jetbrains.annotations.NotNull

The @NotNull annotation is, actually, an explicit contract declaring that:

  • A method should not return null
  • Variables (fields, local variables, and parameters) cannot hold a null value

Usage:

intellij @NotNull

javax.validation.constraints.NotNull

@Target(value={METHOD,FIELD,ANNOTATION_TYPE,CONSTRUCTOR,PARAMETER})
@Retention(value=RUNTIME)
@Documented
@Constraint(validatedBy={})
public @interface NotNull

javax.annotation.Nonnull

@Documented
@TypeQualifier
@Retention(value=RUNTIME)
public @interface Nonnull

Usage:

javax @Nonnull


So feel free to use any one of these four on your method.

Michael
  • 41,989
  • 11
  • 82
  • 128
  • Just to add javax.annotation.Nonnull, edu.umd.cs.findbugs.annotations.NonNull, – rkosegi Jul 25 '18 at 16:54
  • Seems lombok developers refused to add check for non-null return value: https://github.com/rzwitserloot/lombok/issues/907 – gavenkoa Jul 25 '18 at 16:55
  • @rkosegi The umd documentation is on sourceforge, which my company blocks. If you can add the appropriate documentation I would be grateful. – Michael Jul 25 '18 at 16:57
  • Wow! [Java Validation 2.0 works on method return values](http://www.baeldung.com/javax-validation-method-constraints)! Seems that it is not possible to express non-null return value in Java types. Java type system is not enough smart. **The only way is to go with static code analysis tools**. – gavenkoa Jul 25 '18 at 17:02
  • 1
    @gavenkoa Exactly. It sounds like you want Kotlin. [Null was a mistake](https://news.ycombinator.com/item?id=12427069) – Michael Jul 25 '18 at 17:04
0

you can use .OrElse(). See this example

Optional<String> response = Optional.of("Not Null");
    Optional<String> response2 = Optional.empty();
    System.out.println(response.orElse(""));
    System.out.println(response2.orElse("Dont want to return null"));
GolamMazid Sajib
  • 8,698
  • 6
  • 21
  • 39