Setting default values on parameters create overloaded methods with combinations made from left to right, thus, it is hard to make method(12)
and also be able to pass map entries.
Your method def method(paramMap, specificVar1=7, specificVar2=14)
will generate the following methods:
Object Maps.method(java.lang.Object)
Object Maps.method(java.lang.Object,java.lang.Object)
Object Maps.method(java.lang.Object,java.lang.Object,java.lang.Object)
And a fully typed method with the map param:
def method3(Map paramMap=[:], Integer specificVar1=7, Integer specificVar2=14) {
}
Will generate the following methods:
Object Maps.method3()
Object Maps.method3(java.util.Map)
Object Maps.method3(java.util.Map,java.lang.Integer)
Object Maps.method3(java.util.Map,java.lang.Integer,java.lang.Integer)
(No suitable method for method(12)
).
Also, entries passed to the method will be collected and inserted in the first map parameter. The following method:
def method4(Integer specificVar1=7, Integer specificVar2=14, Map map=[:]) {
Generates:
Object Maps.method4()
Object Maps.method4(java.lang.Integer)
Object Maps.method4(java.lang.Integer,java.lang.Integer)
Object Maps.method4(java.lang.Integer,java.lang.Integer,java.util.Map)
Thus, method4 12, a:'b'
fails with:
No signature of method: Maps.method4() is applicable for argument types:
(java.util.LinkedHashMap, java.lang.Integer) values: [[a:b], 12]
So, no, i don't think you can do what you want using maps :-).
Solution 1:
If you are in for a pure dynamic solution, you can use a single map argument:
def method5(Map map) {
def specificVar1 = map.specificVar1 ?: 7
def specificVar2 = map.specificVar2 ?: 14
}
Solution 2 (updated):
You can create a class to represent the parameters. Using a map to be coerced into the object is statically compilable and a syntatic sugar for it.
@groovy.transform.CompileStatic
class Maps {
def method6(Foo foo) { "$foo.params, $foo.specificVar1, $foo.specificVar2" }
def method6(Map map) { method6 map as Foo }
static main(args) {
def maps = new Maps()
assert maps.method6(params: [a: 'b', c: 'd'], specificVar1: 40) ==
"[a:b, c:d], 40, 14"
assert maps.method6(new Foo(params: [a: 'b', c: 'd'], specificVar2: 21)) ==
"[a:b, c:d], 7, 21"
}
}
class Foo {
def specificVar1 = 7, specificVar2 = 14, params = [:]
}
Solution 3:
An overloaded method.
def method6(Map paramMap, Integer specificVar1=7, Integer specificVar2=14) {
"$paramMap, $specificVar1, $specificVar2"
}
def method6(Integer specificVar1=7, Integer specificVar2=14) {
method6 [:], specificVar1, specificVar2
}
assert method6( 12 ) == "[:], 12, 14"
assert method6( ) == "[:], 7, 14"
assert method6( a:'b', 18 ) == "[a:b], 18, 14"
assert method6( 18, a:'b', 27 ) == "[a:b], 18, 27"
assert method6( 90, 100 ) == "[:], 90, 100"
assert method6( a:'b', 140, c:'d' ) == "[a:b, c:d], 140, 14"
The map version method can't have a default parameter, otherwise both methods will generate a parameterless method6
and those will conflict.