Groovy Goodness: Map Methods To Operators
Groovy supports operator overloading since the start. Operator overloading is implemented by an actual method signature that maps to an operator. For example an object with a plus
method can be used with the +
operator. There is a list of methods and operators available on the Groovy website.
As long as an object has a method with a name that Groovy understands the corresponding operator can be used in Groovy code. This is even true for Java objects. Since Groovy 5 you can use the groovy.transform.OperatorRename
annotation on classes, methods or constructors to map other method names to the Groovy operator overloading method names. This is very useful for third-party classes that you cannot change, but still want to use simple operators in Groovy code. You can reassign a method name to the following methods so an operator can be used: plus
, minus
, multiply
, div
, remainder
, power
, leftShift
, rightShift
, rightShiftUnassigned
, and
, or
, xor
, compareTo
. Suppose you use a class with an add
method and want to use the +
operator for this method. The following annotation can be used @OperatorRename(plus = 'add')
for a method and inside the method you can use the +
operator instead of the add
method of the class.
In the following example the methods add
, subtract
and divide
from the class org.javamoney.moneta.Money
are mapped to the +
, -
and /
operators:
@Grab(group='org.javamoney', module='moneta', version='1.4.5', type='pom')
import org.javamoney.moneta.Money // Java library to work with Money objects.
import groovy.transform.OperatorRename
// In the scope of this method several methods are
// mapped to operators.
@OperatorRename(
plus='add', // map add method of Money to + operator
minus='subtract', // map subtract method to - operator
div='divide' // map divide method to / operator
)
void workWithMoney() {
def _10Euro = Money.of(10, "EUR")
def _20Euro = Money.of(20, "EUR")
// First we use the add method of Money.
assert _10Euro.add(_20Euro) == Money.of(30, "EUR")
// Because we redefined the add method to plus
// we can use the + operator as well in this method.
assert _10Euro + _20Euro == Money.of(30, "EUR")
// Using the subtract method of Money to subtract
// two Money objects.
assert _20Euro.subtract(_10Euro) == _10Euro
// The subtract method is redefined to minus,
// so we can use the - operator as well.
assert _20Euro - _10Euro == _10Euro
// The Money class already has a multiply method
// that will automatically map to the * operator.
assert _10Euro.multiply(2) == _20Euro
assert _10Euro * 2 == _20Euro
// To divide a Money object the divide method is
// redefined to the / operator.
assert _20Euro.divide(2) == _10Euro
assert _20Euro / 2 == _10Euro
}
workWithMoney()
Written with Groovy 5.0.0.