我有一个内联函数,带有一个带有lambda的reified类型参数,它返回一个匿名类的新实例,它有一个方法获取该reified类型参数并将其传递给lambda。
inline fun <reified T : Any> eventHandler(crossinline handler: (T) -> Unit) = object {
@Handler
fun event(event: T) = handler(event)
}
它像eventHandler<ExampleEvent> { println(it.data); }
一样使用,所有内容都会编译。
然而,调查在上述调用中创建的类的生成字节码,我得到了事件方法:
public final void event(example.ExampleEvent);
descriptor: (Ljava/lang/Object;)V
[...]
Signature: #53 // (Lexample.ExampleEvent;)V
因此,当它正确记住签名中的类型时,它会在描述符中丢弃它;因此thatEventMethod.getParameterTypes()
将Object
而不是ExampleEvent
。
这是一个错误还是预期的行为?此外,如果是这样的话,是否还有其他方法可以实现我的目标(这是为了防止必须在任何地方创建那个笨拙的对象,用@Handler等添加一个虚拟方法)?
答案 0 :(得分:0)
所以,如果我正确理解您的问题是:在字节码中具有泛型泛型的函数看起来像具有已擦除类型的函数一样。
答案为“是”。这就是为什么带有泛型泛型的函数只能双向内联的原因。他们的身体正被内线插入呼叫者。当然,这里的类型也不会被擦除(以使调用函数字节码大小膨胀为代价)。