Dan*_*ral 31
你的论点是有缺陷的.Kotlin还没有发布*,而且Ceylon刚刚发布了它的第一个版本,我将引用其公告中缺少的一件事:
- 具体化的仿制药
所以,原谅我,但什么实施证明这是可能的吗?事实上,我并没有太多关注Kotlin的承诺,但锡兰所承诺的只是已经提供的内容,而是以透明的方式.
但是,让我们考虑一下您在问题中描述的问题:
trait Handles[E <: Event] {
def handle(event: E)
}
Run Code Online (Sandbox Code Playgroud)
因此,首先,JVM不提供任何方法来识别接口或类中的类型参数,因此JVM E 无法检查.但是,您可以存储有关E实现的每个对象中的内容的信息Handles,就像您可以在Scala中编写它一样:
abstract class Handles[E <: Event : Manifest] {
def handle(event: E)
}
Run Code Online (Sandbox Code Playgroud)
接下来,让我们看看方法handle.同样,JVM无法在方法定义中使用类型参数.实现它的唯一方法是将handleaccept Object作为参数:即,键入擦除.
这是交易:handle要从Java调用,它必须被删除类型.并且,如果它是类型擦除,那么它受到您的问题中描述的限制.解决这个问题的唯一方法就是放弃Java兼容性(顺便说一句,这在Ceylon的第一个版本中也是不可用的).
是的,根据Martin Odersky的说法,Scala将在2.10上具有某种特定性.但无论它提供什么(我打赌更透明地使用清单来断言类型相等),这个特殊限制是JVM固有的,并且在不丢弃Java集成的情况下无法克服.
(*)Kotlin现在已经有了一个演示版,它的具体化 - 到目前为止 - 只是捆绑清单和instanceOf测试的语法糖.它仍然受到Scala所有相同的限制.
Kotlin已经为内联函数类型参数确定了泛型,如下所述:https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters.这已经存在于Kotlin已有一段时间了,它们已经被Kotlin生态系统中的许多图书馆所使用.这里的其他答案在提到Kotlin时已经过时了. Kotlin自2016年2月起发布为1.0.
TypeReference在Jackson Kotlin模块中使用的Kotlin中着名的仿制品的例子使用此代码:
public inline fun <reified T: Any> ObjectMapper.readValue(jp: JsonParser): T
= readValue(jp, object: TypeReference<T>() {})
Run Code Online (Sandbox Code Playgroud)
基于Kotlin的Injekt图书馆也是如此:
public inline fun <reified T: Any> fullType(): FullTypeReference<T>
= object:FullTypeReference<T>(){}
public inline fun <reified T : Any> injectLazy(): Lazy<T> {
return lazy { Injekt.get(fullType<T>()) }
}
Run Code Online (Sandbox Code Playgroud)