The Checker Framework Manual:
Custom pluggable types for Java

Chapter 25 Returns Receiver Checker

The Returns Receiver Checker enables documenting and checking that a method returns its receiver (i.e., the this parameter).

There are two ways to run the Returns Receiver Checker.

  • • Typically, it is automatically run by another checker.

    If the code being checked does not use fluent APIs, you can pass the -AdisableReturnsReceiver command-line option. This disables the Returns Receiver Checker and makes the other checker run faster.

  • • Alternatively, you can run just the Returns Receiver Checker by supplying the following command-line option to javac: -processor org.checkerframework.common.returnsreceiver.ReturnsReceiverChecker

25.1 Annotations

The qualifier @This on the return type of a method indicates that the method returns its receiver. Methods that return their receiver are common in so-called “fluent” APIs. Here is an example:

class MyBuilder {
  @This MyBuilder setName(String name) {
    this.name = name;
    return this;
  }
}

A @This annotation can only be written on a return type, on a receiver type, or in a downcast.

As is standard, the Returns Receiver Checker has a top qualifier, @UnknownThis, and a bottom qualifier, @BottomThis. Programmers rarely need to write these annotations.

Here are additional details. @This is a polymorphic qualifier rather than a regular type qualifier (see Section 32.2). Conceptually, a receiver type always has a @This qualifier. When a method return type also has a @This qualifier, the presence of the polymorphic annotation on both the method’s return and receiver type forces their type qualifiers to be equal. Hence, the method will only pass the type-checker if it returns its receiver argument, achieving the desired checking.

25.2 AutoValue and Lombok support

@AutoValue
abstract class Animal {
  abstract String name();
  abstract int numberOfLegs();
  static Builder builder() {
    return new AutoValue_Animal.Builder();
  }
  @AutoValue.Builder
  abstract static class Builder {
    abstract Builder setName(String value);        // @This is automatically added here
    abstract Builder setNumberOfLegs(int value);   // @This is automatically added here
    abstract Animal build();
  }
}

Figure 25.1: User-written code that uses the @AutoValue.Builder annotation. Given this code, (1) AutoValue automatically generates a concrete subclass of Animal.Builder, see Figure 25.2, and (2) the Returns Receiver Checker automatically adds @This annotations on setters in both user-written and automatically-generated code.

    class AutoValue_Animal {
      static final class Builder extends Animal.Builder {
        private String name;
        private Integer numberOfLegs;
        @This Animal.Builder setName(String name) {
          this.name = name;
          return this;
        }
        @This Animal.Builder setNumberOfLegs(int numberOfLegs) {
          this.numberOfLegs = numberOfLegs;
          return this;
        }
        @Override
        Animal build() {
          return new AutoValue_Animal(this.name, this.numberOfLegs);
        }
      }
    }

Figure 25.2: Code generated by AutoValue for the example of Figure 25.1, including the @This annotations added by the Returns Receiver Checker.

The AutoValue and Lombok projects both support automatic generation of builder classes, which enable flexible object construction. For code using these two frameworks, the Returns Receiver Checker automatically adds @This annotations to setter methods in builder classes. All the @This annotations in Figures 25.1 and 25.2 are automatically added by the Returns Receiver Checker.