Java确保使用相同的通配符捕获类型

时间:2017-01-31 13:45:01

标签: java generics types

我得到两个对象o1:T,o2:来自asource的消费者归结为:

public interface MySource<T> {
    Class<T> getType();

    Consumer<T> getComsumer();
}

我想将它们反馈给一个通用方法,该方法要求两者具有相同的Type(参数)。

public interface Registry<M> {
    <T extends M> void register(Class<T> type, Consumer<T> consumer);
}

从某个地方我得到了一个未知类型的MySource。

Java并不足以推断,存在类型实际上是相同的。

public abstract class Example<M> {
    Registry<M> registry;

    static MySource<? extends M> getSrc();

    public <T extends M> void register(Class<T> type) {
        MySource<? extends M> src = getSrc();
        registry.register(src.getType(), src.getComsumer());
    }

> The method register(Class<T>, Consumer<T>) in the type
> Registry<M> is not applicable for the arguments
> (Class<capture#3-of ? extends M>, Consumer<capture#4-of ? extends M>)

我必须将结果包装在另一个对象中吗?或者有更好的方法来解决这个问题?

2 个答案:

答案 0 :(得分:1)

扭转局限:

MySource<M> src;
Registry<? super M> registry;

然后你的registry.register(src.getType(), src.getComsumer());工作正常。

您可能需要一个小的包装器方法来执行此操作:

<M> void wrapRegister(MySource<M> src, Registry<? super M> registry) {
  registry.register(src.getType(), src.getComsumer());
}

然后:

MySource<? extends M> src = ...;
Registry<M> registry = ...;
wrapRegister(src, registry);

Ideone demo

答案 1 :(得分:0)

是的,Java确实不够聪明。但是,您可以使用反射来调用您的方法:

try {
    Method registerMethod = registry.getClass().getMethod("register", Class.class, Consumer.class);
    registerMethod.invoke(registry, src.getType(), src.getConsumer());
} catch (Exception e){
    e.printStackTrace();
    // generics didn't match or something else went wrong, you can catch specific Exceptions from reflective .invoke() method   
}

这应该可以解决问题。