当前位置: 首页 > 知识库问答 >
问题:

java中泛型方法的推理

谷梁嘉悦
2023-03-14

如果我有类class<,那么我会得到以下场景?扩展imodel<?>>ACL和collectioncollection<?扩展IModel<?>>EntitiesCollection并尝试将它们传递给方法 >void doIndex(类 clz,iterable 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) 

其中params、clz和items基于相同的类型t,当我们只有一个参数时,可以使用通配符捕获方法。但这里有通配符变量clsentitiescollection:

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

它们与clzitems具有类似的关系,但我不知道如何将它们传递到doindex中。

共有1个答案

鲁斯伯
2023-03-14

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

如果doindex有两个类型参数tC格式 ,您可以使用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);

为什么?与前面的问题相同:CL不一定与EntitiesCollection相同。

不知道有没有好的解决办法。如果在调用方法上也使用 > 之类的类型参数,然后在整个代码中使用t而不是问号,则可以使对doindex的调用工作。

如果真的不能这样做(有时也是这样),并且必须到处使用问号,在我看来,类型参数似乎没有用,应该删除或绕过。您可能知道这一点,但不安全的强制转换以移除泛型,即使使用原始的方法声明也可以完成工作:

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相互兼容。(但是,如果iterable不为空,则该方法可以执行运行时检查,以查看其中的对象是否与class参数兼容。)

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

 类似资料:
  • 问题内容: 如果在Java中创建泛型类(该类具有泛型类型参数),则可以使用泛型方法(该方法带有泛型类型参数)吗? 考虑以下示例: 正如您对通用方法所期望的那样,我可以使用任何对象调用的实例: 但是,如果我尝试使用 不 指定泛型类型的实例,则无论传入什么,我都会调用返回, 奇怪的是,如果返回类型是通用类,它将编译(例如(实际上,这可以解释-参见下面的答案)): 此外,如果输入通用类,即使仅使用通配符

  • 如果在Java中创建泛型类(该类具有泛型类型参数),是否可以使用泛型方法(该方法采用泛型类型参数)? 考虑下面的例子: 正如您所期望的那样,对于任何对象,的实例,我都可以调用: 但是,如果我试图使用的实例而不指定泛型类型,那么调用将返回一个

  • 安吉丽卡·兰格(Angelica Langer)在关于仿制药的常见问题解答中说(参见Technicalities.FAQ822): 如果这些方法具有具有不同边界的类型参数,则它们不会重写,因为这些方法的签名不是重写等价的。请记住,类型参数边界是泛型方法签名的一部分。 示例(泛型子类型方法重载泛型超类型方法;不推荐): 我不明白为什么方法在类中重载。据我所知,这应该是一个编译时错误,因为在和中具有相

  • 问题内容: 在C#中,我实际上可以这样做: 但是由于某种原因,我无法使其在Java中工作。 我要做的是在超类上创建一个静态方法,以便可以将子类转换为XML。 问题答案: 称为: 或更明确地: 更令人困惑的是,您可以拥有既构造泛型类型又具有泛型参数的构造函数。不记得该语法,也从未在愤怒中使用过它(无论如何,最好还是使用静态创建方法)。 强制转换是不安全的,并且您不能编写T.class。因此,将T.c

  • 我正在尝试创建一个通用类,该类将使用java中的3个数字(在我的例子中是int、float和double)。 在这个类中,我需要一个double方法,该方法将返回最大数量的3,但我很难返回double,因为它是一个泛型类。 这是我到目前为止所拥有的,但是当用整数测试它时,我得到了以下错误: Java语言lang.ClassCastException:java。lang.Integer不能转换为ja

  • Main.java:12:错误:TextMessage不是抽象的,并且不会覆盖Message类中的抽象方法setContent(T)TextMessage扩展Message{^其中T是类型变量:T扩展方法setContent(T)中声明的Object 1错误