我刚刚开始探索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
}
基于上面的代码 - 我可以期待发生什么?我是否在运行时失败,因为Horse没有实现添加(动物)?它是否可以在上述性质的调用中准确区分它们,其中被比较的值的编译时类型是Animal(至少是写入的),但它们的运行时类型更具体?如果我们使用var而不是val,它会改变什么吗?
提前致谢 .
编辑:修改核心代码 - 我看到第一响应者强调的问题,我没有直接思考 . 显然我还没有编译过这个,我仍然在概念层面进行探索 .
另外,我会在实际的编译器中给它一个镜头,但是我担心会出现它工作的情况,而其他情况则不会基于我不完全理解的某些标准 . 我无法找到关于如何在Kotlin中实现动态调度的参考文档(对于Java来说也不确定它是什么意思;几个月前我写了一些我认为可以基于JVM文档工作的东西,但它没有不,我从来没有机会探究到底为什么 .
无论如何再次感谢!
2 回答
所以这是一个实际编译的代码版本:
结果是“Animal @ 1906bcf8” .
据我所知,扩展方法,即
Horse.plus(x:Horse)
和Horse.plus(x:Donkey)
,是静态调度的 . 那是因为它们被基本编译为与以下Java代码相同的字节代码:顺便说一句,这与Java 8中的默认方法有很大不同,它们是基于运行时类型动态调度的,可以被覆盖 .
这段代码根本不可编译,因为Animal没有任何“”运算符 .
如果他们允许在Animal上使用Horse“”方法,那么你会得到运行时错误,kotlin / java / etc . 试图阻止 .
Kotlin不会使用运行时类型来解决方法和内容,因为有可能产生运行时错误 .
如果另一个线程在此期间将Animal更改为Mule,另一个线程更改Animal的确切行/时间不确定,那么这可能会导致运行时错误 .
Val或var在这种情况下不会改变任何东西 .