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@AutoImplement
class 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@AutoImplement
class 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 |
code If defined, all unimplemented methods will execute the code found within the supplied closure. |
Class<? extends RuntimeException> |
exception If defined, all unimplemented methods will throw this exception. |
String |
message If 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