Class annotation used to provide default dummy methods for a class extending an abstract super class or implementing one or more interfaces.
Example usage:
import groovy.transform.AutoImplementIn the above example, since@AutoImplementclass EmptyStringIterator implements Iterator{ boolean hasNext() { false } } assert !new EmptyStringIterator().hasNext()
hasNext returns false, the next method
should never be called, so any dummy implementation would do for next.
The "empty" implementation provided by default when using @AutoImplement
will suffice - which effectively returns null in Groovy for non-void,
non-primitive methods.
As a point of interest, the default implementation for methods returning primitive
types is to return the default value (which incidentally never satisfies Groovy truth).
For boolean this means returning false, so for the above example we
could have (albeit perhaps less instructive of our intent) by just using:
If we didn't want to assume that callers of our@AutoImplementclass EmptyStringIterator implements Iterator{ }
EmptyStringIterator correctly followed
the Iterator contract, then we might want to guard against inappropriate calls to next.
Rather than just returning null, we might want to throw an exception. This is easily done using
the exception annotation attribute as shown below:
import groovy.transform.AutoImplement import static groovy.test.GroovyAssert.shouldFailAll implemented methods will throw an instance of this exception constructed using its no-arg constructor. You can also supply a single@AutoImplement(exception=UnsupportedOperationException) class EmptyStringIterator implements Iterator{ boolean hasNext() { false } } shouldFail(UnsupportedOperationException) { new EmptyStringIterator().next() }
message annotation attribute in which case the message will be passed
as an argument during exception construction as shown in the following example:
Finally, you can alternatively supply a@AutoImplement(exception=UnsupportedOperationException, message='Not supported for this empty iterator') class EmptyStringIterator implements Iterator{ boolean hasNext() { false } } def ex = shouldFail(UnsupportedOperationException) { new EmptyStringIterator().next() } assert ex.message == 'Not supported for this empty iterator'
code annotation attribute in which case a closure
block can be supplied which should contain the code to execute for all implemented methods. This can be
seen in the following example:
@AutoImplement(code = { throw new UnsupportedOperationException("Not supported for ${getClass().simpleName}") }) class EmptyStringIterator implements Iterator{ boolean hasNext() { false } } def ex = shouldFail(UnsupportedOperationException) { new EmptyStringIterator().next() } assert ex.message == 'Not supported for EmptyStringIterator'
| Type | Name and Description |
|---|---|
Class |
codeIf defined, all unimplemented methods will execute the code found within the supplied closure. |
Class<? extends RuntimeException> |
exceptionIf defined, all unimplemented methods will throw this exception. |
String |
messageIf exception is defined, message can be used to specify the exception message.
|
If defined, all unimplemented methods will execute the code found within the supplied closure. @default .CLASS.class
If defined, all unimplemented methods will throw this exception.
Will be ignored if code is defined.
@default .EXCEPTION.class
If exception is defined, message can be used to specify the exception message.
Will be ignored if code is defined or exception isn't defined.
@default Undefined.STRING