Reputation: 42229
Consider the following code:
class Foo(val bar: String, val baz: Boolean = true) {
constructor(bar: String) : this(bar, false)
}
Without the addition of a secondary constructor, I could call Foo("")
because the second argument has a default value. This would result in baz
being true
.
With the addition of a secondary constructor, I can still call Foo("")
, except that now baz
is false
.
Why does Kotlin not see this as a duplicate constructor signature, since they can both be called with the same arguments?
Upvotes: 5
Views: 5574
Reputation: 29844
If you take a look at the bytecode there are actually three constructors generated, as Roland already pointed out.
public Foo(@NotNull String bar, boolean baz) { ... }
public Foo(String var1, boolean var2, int var3, DefaultConstructorMarker var4) { ... }
public Foo(@NotNull String bar) { ... }
So, there are no duplicate constructor signatures. Now one might ask how Kotlin chooses which overload to take judging from the call-site only.
The overall rationale is that the most specific function/constructor will be chosen from the overload candidates.
This is what the Kotlin language specification says about it:
For each candidate, we count the number of default parameters not specified in the call (i.e., the number of parameters for which we use the default value);
The candidate with the least number of non-specified default parameters is a more specific candidate;
I know that you intended this to only be an example, but if something like this happens in a real-world situation one should avoid it like the Kotlin Language Documentation (page 76) states:
If you have an object with multiple overloaded constructors that don't call different superclass constructors and can't be reduced to a single constructor with default argument values, prefer to replace the overloaded constructors with factory functions.
class Foo2(val bar: String, val baz: Boolean = true) {
companion object {
fun factoryCreate(s: String) = Foo2(s, false)
}
}
In this case it will always be clear right away (without thinking about the overloading resolution rules) what baz
will be after creation.
Upvotes: 6