Kotlin-构造函数默认值和构造函数重载

时间:2019-09-10 15:02:47

标签: kotlin

考虑以下代码:

class Foo(val bar: String, val baz: Boolean = true) {
    constructor(bar: String) : this(bar, false)
}

在不添加辅助构造函数的情况下,我可以调用Foo(""),因为第二个参数具有默认值。这将导致baztrue

除了第二个构造函数之外,我仍然可以调用Foo(""),除了现在bazfalse

为什么Kotlin不会将其视为重复的构造函数签名,因为它们都可以使用相同的参数来调用?

1 个答案:

答案 0 :(得分:4)

正如Roland所指出的那样,如果看一下字节码,实际上生成了三个构造函数。

public Foo(@NotNull String bar, boolean baz) { ... }
public Foo(String var1, boolean var2, int var3, DefaultConstructorMarker var4) { ... }
public Foo(@NotNull String bar) { ... }

因此,没有重复的构造函数签名。现在,人们可能会问Kotlin如何选择仅从呼叫站点来判断哪个过载。

总体理由是,将从重载候选中选择最具体的函数/构造函数。

这是Kotlin language specification所说的:

  
      
  • 对于每位候选人,我们计算通话中未指定的默认参数的数量(即,我们使用的默认参数的数量)   默认值);

  •   
  • 未指定默认参数最少的候选人是更具体的候选人;

  •   

我知道您只是想举一个例子,但是如果在现实情况下发生这种情况,应该避免使用Kotlin Language Documentation(第76页)状态:

  

如果您的对象具有多个重载的构造函数,而这些构造函数没有   调用不同的超类构造函数,并且不能简化为   具有默认参数值的单个构造函数,建议替换为   具有工厂功能的重载构造函数。

class Foo2(val bar: String, val baz: Boolean = true) {
    companion object {
        fun factoryCreate(s: String) = Foo2(s, false)
    }
}

在这种情况下,始终会很清楚(无需考虑重载解决方案规则)创建后baz是什么。