java - java 中的泛型方法推断

标签 java generics

如果我类的话,我会遇到以下场景 Class<? extends IModel<?>> aCls和 Collection Collection<? extends IModel<?>> entitiesCollection并尝试将它们传递给方法 <T extends IModel<T>> void doIndex(Class<T> clz, Iterable<T> items) ,但不断出现编译时异常。我尝试了通配符捕获和其他方法,但没有运气。我一定错过了一些明显的东西。将不胜感激任何建议。

Multimap<Class<? extends IModel<?>>, IModel<?>> entityMultimap = ArrayListMultimap.create();

for (IModel<?> entity  : models) {

      Class<? extends IModel<?>> aCls = entity.getClass();
       entityMultimap.put(aCls, entity);          
    }



for (Class<? extends HasKey<?>> cls : entityMultimap.keySet()) {
   Collection<? extends IModel<?>> entitiesCollection = entityMultimap.get(cls);
        doIndex(cls, entitiesCollection);
}


public static <T extends IModel<T>> void doIndex(Class<T> clz, Iterable<T> items) {

    .....
}

更新:有人将此标记为与其他通用通配符相关问题的重复。然而,这是非常不同的情况。我们拥有的是

public static <T extends IModel<T>> void doIndex(Class<T> clz, Iterable<T> items) 

其中参数 clz 和基于相同类型 T 的项目。可以使用 wildcard capture方法,以防我们只有一个参数。但这里我们有通配符变量 clsentitiesCollection :

 Class<? extends HasKey<?>> cls and
 Collection<? extends IModel<?>> entitiesCollection 

clz 具有类似的关系和items ,但我不知道如何将它们传递到doIndex

最佳答案

一个Foo<? extends IModel<?>>不能被视为 Foo<T extends IModel<T>> 。这是不一样的。两者中的每一个? s 是独立的,可能指的是不同的未知事物,但两者都是T s 指的是相同的未知事物。

如果doIndex有两个类型参数 TC格式为:<T,C extends IModel<T>> ,您可以使用 Class 来调用它参数或 Iterable参数,但仍然不能同时两者。所以这将编译:

static <T,C extends IModel<T>> void doIndex(Class<C> clz, Iterable<C> items) {}
static {
    Class<? extends IModel<?>> cls = null;
    Collection<? extends IModel<?>> entitiesCollection = null;
    doIndex(cls, null);
    doIndex(null, entitiesCollection);
}

但是这个额外的行不会编译:

    doIndex(cls, entitiesCollection);
为什么?与之前相同的问题:cls? s 不一定是与 entitiesCollection 相同的未知事物。的? s。

不知道有没有好的解决办法。您也许可以调用 doIndex如果您使用类似 <T extends IModel<T>> 的类型参数,则可以工作也在调用方法上,然后使用 T整个代码而不是问号。

如果确实无法做到这一点(有时是这种情况),并且您必须在各处使用问号,那么在我看来,类型参数没有用,应该删除或绕过。您可能知道这一点,但即使使用原始方法声明,删除泛型的不安全转换也能完成工作:

static <T extends IModel<T>> void doIndex(Class<T> clz, Iterable<T> items) {}
static {
    Class<? extends IModel<?>> cls = null;
    Collection<? extends IModel<?>> entitiesCollection = null;
    doIndex((Class)cls, (Collection)entitiesCollection); // has a warning, but compiles
}

或者,doIndex 的约束可以放松一下。此声明doIndex使其在没有警告的情况下工作,因为它不再关心类型是否相同:

static void doIndex(Class<? extends IModel<?>> clz, Iterable<? extends IModel<?>> items) {}

优点也是缺点:doIndex不能再问ClassIterable彼此兼容。 (但是,如果可迭代不为空,该方法可以执行运行时检查以查看其中的对象是否与类参数兼容。)

根本问题是doIndex要求对其参数的参数类型进行约束,但您没有满足的信息,因为所有其他类型参数都是问号。

关于java - java 中的泛型方法推断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24591506/

相关文章:

java - 'UnexpectedTagNameException' 和 Element 应该是 "select",但通过 Selenium java 使用 "div"函数却出现 'Select' 错误

c# - 从 bool 返回类型的泛型方法返回 bool 值

java - 是否可以通过将 "new Object()"转换为泛型类来实例化泛型类?

Scala - 在父类中引用子类(泛型)

C# 在不知道类型的情况下返回类型

实现协议(protocol)类型的swift方法参数?

java - 链表或递归调用 HashMap

java 使用Executor实现多线程

Java 编译器重新排序

java - 无法从 Android 设备获取所有歌曲