kotlin - Kotlin - 构造函数默认值和构造函数重载
问题描述
考虑以下代码:
class Foo(val bar: String, val baz: Boolean = true) {
constructor(bar: String) : this(bar, false)
}
如果不添加辅助构造函数,我可以调用Foo("")
,因为第二个参数具有默认值。baz
这将导致true
.
添加辅助构造函数后,我仍然可以调用Foo("")
,除了 nowbaz
是false
.
为什么 Kotlin 不将其视为重复的构造函数签名,因为它们都可以使用相同的参数调用?
解决方案
如果你看一下字节码,实际上生成了三个构造函数,正如 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 语言规范所说的:
对于每个候选者,我们计算调用中未指定的默认参数的数量(即我们使用默认值的参数的数量);
具有最少数量的未指定默认参数的候选者是更具体的候选者;
我知道您打算将这仅作为一个示例,但是如果在现实世界中发生这种情况,则应该像Kotlin 语言文档(第 76 页)所述那样避免这种情况:
如果您的对象具有多个重载构造函数,这些构造函数不调用不同的超类构造函数,并且不能简化为具有默认参数值的单个构造函数,则更愿意将重载构造函数替换为工厂函数。
class Foo2(val bar: String, val baz: Boolean = true) {
companion object {
fun factoryCreate(s: String) = Foo2(s, false)
}
}
在这种情况下,它总是会立即清楚(无需考虑重载解析规则)baz
创建后会发生什么。
推荐阅读
- css - 角度动画:填充不以高度 0->* 进行动画处理
- excel - 如何更改字符 laravel excel maatwebsite 的颜色?
- php - 将 Laravel 5.4 升级到 5.6 的问题
- php - 在 PHP 中将 Google Charts p 属性添加到 JSON
- c - 猜谜游戏 - 无法弄清楚为什么它会产生一个大的负整数
- visual-studio-2015 - 由于 SSL,Visual Studio nuget 失败
- git - 如何执行不检查遥控器的 Git 状态?
- javascript - 为计算的输出(货币)添加前缀
- jquery - 在您更改月份之前,不会触发 inline datepicker beforeshowday
- docker - 使用 Harbor 复制时出现 401“需要身份验证”