我刚刚开始探索Kotlin,我很好奇它超越了Java的核心动态绑定/调度语义。
让我们说我写的代码看起来像这样:
class Animal { fun add(x:Animal) = Animal() } object Horse : Animal object Donkey : Animal object Mule : Animal fun Horse.add(x:Horse) = Horse() fun Horse.add(x:Donkey) = Mule() fun main(args : Array) { val h:Animal = Horse val d:Animal = Donkey val child = h + d }
根据以上代码 - 我可以期待发生什么?我是否在运行时失败,因为马没有实现添加(动物)?它是否可以在上述性质的调用中准确区分它们,其中被比较的值的编译时类型是Animal(至少如编写),但它们的运行时类型更具体?如果我们使用var而不是val来改变它吗?
提前致谢。
编辑:改进的核心代码 - 我看到第一个响应者强调的问题,我没有直接思考。很明显,我还没有实际编译过这个,我仍然在概念层面进行探索。另外,我会在实际的编译器中给出一个镜头,但是我担心会有某些情况可以运行,而其他情况则根据我没有&#的某些标准。 39;完全明白。我无法找到关于如何在Kotlin中实现动态调度的参考文档(对于Java也不确定它是什么意思;几个月前我写了一些我认为可以基于JVM文档工作的东西,但是它没有,我从来没有机会探究到底为什么。)
无论如何再次感谢!
答案 0 :(得分:6)
所以这里是您实际编译的代码版本:
fun main(vararg args: String) {
val h:Animal = Horse
val d:Animal = Donkey
val child = h + d
println(child)
}
open class Animal {
fun plus(x:Animal) = Animal()
}
object Horse : Animal()
object Donkey : Animal()
object Mule : Animal()
fun Horse.plus(x:Horse) = Horse
fun Horse.plus(x:Donkey) = Mule
结果是" Animal @ 1906bcf8"。
据我了解,扩展方法(即Horse.plus(x:Horse)
和Horse.plus(x:Donkey)
)是静态调度的。这是因为它们被基本编译为与以下Java代码相同的字节代码:
static Horse plus(Horse $receiver, Horse x) {
return Horse.INSTANCE;
}
顺便说一下,这与Java 8中的默认方法有很大不同,默认方法是根据运行时类型动态调度的,可以覆盖。
答案 1 :(得分:0)
此代码根本无法编译,因为Animal没有任何" +"运算符。
如果他们允许使用Horse" +"关于动物的方法, 然后你得到运行时错误,kotlin / java / etc。试图阻止。
Kotlin不会使用运行时类型来解决方法和内容, 因为有可能产生运行时错误。
如果另一个线程在此期间将Animal更改为Mule,另一个线程更改Animal的确切行/时间不确定,那么这可能会导致运行时错误。
Val或var在这种情况下没有任何改变。