Package groovy.transform
Annotation Type AutoImplement
@Documented
@Retention(SOURCE)
@Target(TYPE)
public @interface AutoImplement
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'
- Since:
- 2.5.0
-
Optional Element Summary
Optional Elements Modifier and Type Optional Element Description java.lang.ClasscodeIf defined, all unimplemented methods will execute the code found within the supplied closure.java.lang.Class<? extends java.lang.RuntimeException>exceptionIf defined, all unimplemented methods will throw this exception.java.lang.StringmessageIfexceptionis defined,messagecan be used to specify the exception message.
-
Element Details
-
exception
java.lang.Class<? extends java.lang.RuntimeException> exceptionIf defined, all unimplemented methods will throw this exception. Will be ignored ifcodeis defined.- Default:
- groovy.transform.Undefined.EXCEPTION.class
-
message
java.lang.String messageIfexceptionis defined,messagecan be used to specify the exception message. Will be ignored ifcodeis defined orexceptionisn't defined.- Default:
- "<DummyUndefinedMarkerString-DoNotUse>"
-
code
java.lang.Class codeIf defined, all unimplemented methods will execute the code found within the supplied closure.- Default:
- groovy.transform.Undefined.CLASS.class
-