Groovy name and default arguments

Groovy supports both standard and named arguments. I just don't see them working together.

I need some classes to support building using simple unnamed arguments and using named arguments, as shown below:

def a1 = new A(2) def a2 = new A(a: 200, b: "non default") class A extends SomeBase { def props A(a=1, b="str") { _init(a, b) } A(args) { // use the values in the args map: _init(args.a, args.b) props = args } private _init(a, b) { } } 

Is it usually good practice to support both at the same time? Is the above code the only way?

+4
source share
1 answer

This code will cause some problems. In particular, it will generate two constructors with one Object parameter. The first constructor generates a bytecode equivalent to:

 A() // a,b both default A(Object) // a set, b default A(Object, Object) // pass in both 

The second generates this:

 A(Object) // accepts any object 

You can work around this problem by adding several types. Although groovy has dynamic typing, type declarations in methods and constructors still matter. For instance:

 A(int a = 1, String b = "str") { ... } A(Map args) { ... } 

As for good practices, I would just use one of groovy.transform.Canonical or groovy.transform.TupleConstructor . They will automatically create the correct property maps and positional parameter constructors. TupleConstructor provides only constructors, Canonical applies some other recommendations regarding equals , hashCode and toString .

+6
source

All Articles