Java Language Annotations for 'this' and receiver parameters


Example

When Java annotations were first introduced there was no provision for annotating the target of an instance method or the hidden constructor parameter for an inner classes constructor. This was remedied in Java 8 with addition of receiver parameter declarations; see JLS 8.4.1.

The receiver parameter is an optional syntactic device for an instance method or an inner class's constructor. For an instance method, the receiver parameter represents the object for which the method is invoked. For an inner class's constructor, the receiver parameter represents the immediately enclosing instance of the newly constructed object. Either way, the receiver parameter exists solely to allow the type of the represented object to be denoted in source code, so that the type may be annotated. The receiver parameter is not a formal parameter; more precisely, it is not a declaration of any kind of variable (§4.12.3), it is never bound to any value passed as an argument in a method invocation expression or qualified class instance creation expression, and it has no effect whatsoever at run time.

The following example illustrates the syntax for both kinds of receiver parameter:

public class Outer {
    public class Inner {
        public Inner (Outer this) {
           // ...
        }
        public void doIt(Inner this) {
           // ...
        }
    }
}

The sole purpose of receiver parameters is to allow you to add annotations. For example, you might have a custom annotation @IsOpen whose purpose is to assert that a Closeable object has not been closed when a method is called. For example:

public class MyResource extends Closeable {
    public void update(@IsOpen MyResource this, int value) {
        // ...
    }

    public void close() {
        // ...
    }
}

At one level, the @IsOpen annotation on this could simply serve as documentation. However, we could potentially do more. For example:

  • An annotation processor could insert a runtime check that this is not in closed state when update is called.
  • A code checker could perform a static code analysis to find cases where this could be closed when update is called.