我使用内部Java框架,其中包含以下类(为演示而简化):
public interface SomeAction<T, R> {
R run(T t);
}
public class ConcreteAction implements SomeAction<Integer, String> {
@Override
public String run(Integer arg) {
return "abc";
}
}
public class ActionFactory {
public <A extends SomeAction<T, R>, T, R> SomeAction<T, R> create(Class<A> clz) throws IllegalAccessException, InstantiationException {
return clz.newInstance();
}
}
以Java方式从Kotlin调用factory方法可以正常工作:
ActionFactory().create(ConcreteAction::class.java).run(1)
然后,我创建了以下扩展方法以使其更简洁:
inline fun <reified A : SomeAction<T, R>, T, R> ActionFactory.create(): SomeAction<T, R> {
return create(A::class.java)
}
但是调用ActionFactory().create<ConcreteAction>().run(1)
失败,并显示错误3 type arguments for inline fun ...
有什么方法可以使它在不触碰Java代码的情况下工作?
答案 0 :(得分:2)
Kotlin不允许仅指定一部分类型参数而调用泛型函数。如果要使用显式类型参数调用create
,则必须指定所有三个参数:
ActionFactory().create<ConcreteAction, Int, String>().run(1)
答案 1 :(得分:0)
注意:这可能不适用于实际代码,具体取决于您简化的内容。但是,在进行此设置后,可以合理假设create
的返回值实际上是A
的实例,在这种情况下
inline fun <reified A : SomeAction<*, *>> ActionFactory.create(): A {
return create(A::class.java) as A
}
ActionFactory().create<ConcreteAction>().run(1)
将起作用。如果您这样做的话,应该记录该假设并添加测试!