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:
this
is not in closed state when update
is called.this
could be closed when update
is called.