参数化返回类型的Kotlin函数修饰参数

时间:2019-11-13 07:02:52

标签: generics kotlin kotlin-reified-type-parameters

我使用内部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代码的情况下工作?

2 个答案:

答案 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)

将起作用。如果您这样做的话,应该记录该假设并添加测试!