Reputation: 4643
In Groovy, if I have:
def say(msg = 'Hello', name = 'world') {
"$msg $name!"
}
And then call:
say() // Hello world!
say("hi") // Hi world!
say(null) // null world!
Why is the last one getting interpreted literally as null
and not applying the default value? Doesn't this defeat the purpose of default method argument values? I do get that passing null
is different from not passing anything w/r/t argument length.
My problem here is that if I now have a method that takes a collection as an argument:
def items(Set<String> items = []) {
new HashSet<>(items)
}
This will throw a NullPointerException
if I call items(null)
but work fine if I just say items()
. In order for this to work right, I have to change the line to be new HashSet<>(items ?: [])
which, again, seems to defeat the entire purpose of having default method argument values.
What am I missing here?
Upvotes: 9
Views: 8667
Reputation: 14529
In Groovy, default parameters generates overloaded methods. Thus, this:
def items(Set<String> items = []) {
new HashSet<>(items)
}
Will generate these two methods (I used javap
to get these values):
public java.lang.Object items(java.util.Set<java.lang.String>);
public java.lang.Object items();
So when you call items(null)
you are, in fact, passing some value, and items(Set)
method will be used.
You can also refer to this question about default parameters.
Upvotes: 12