当前位置: 首页 > 面试题库 >

编译器自动绑定泛型类型(类型推断)

李成礼
2023-03-14
问题内容

以下代码在t3行中出现编译错误:

public <E> List<E> getList()
{
    return new ArrayList<E>();
}
public <T> void first()
{
    List<T> ret = new ArrayList<T>();
    List<T> list = getList();
    T t1 = ret.get(0);
    T t2 = list.get(0);
    T t3 = getList().get(0);
}

错误消息是: 类型不匹配:无法从对象转换为T

我知道我可以使用强制转换或手动绑定来解决问题,我的问题是: 编译器进行自动绑定是否如此困难,是否会失败?

编辑:添加了错误消息。

编辑:添加了另一个示例如何不会发生该错误。

编辑:删除了第二个示例,因为它令人困惑,使问题更加清楚。


问题答案:

在第一种情况下,您有两个具有名为的类型参数的泛型方法T,但是这些类型参数是不同的,因此让我们为其分配不同的名称:

public <E> List<E> getList() { ... }
public <T> void first() { ... }

然后,它的工作方式如下:

  1. 的元素List<T>(即type的对象T)分配给type的变量T,因此一切正常:

     List<T> ret = new ArrayList<T>();
    

    T t1 = ret.get(0);

  2. 首先,将类型的对象List<E>分配给List<T>。该语句工作得很好,因为类型参数E是从赋值左侧的类型推断出来的,所以T= E。然后,它与前面的情况一样工作:

     List<T> list = getList();
    

    T t2 = list.get(0);

  3. 在这种情况下,您尝试将type的对象分配给type E的变量T,但是E无法进行推断并因此假定为Object,因此分配失败:

      T t3 = getList().get(0);
    

您可以通过手动绑定E来解决此问题T

      T t3 = this.<T>getList().get(0);

在泛型类的情况下,TestGenerics<T>您没有两个独立的类型参数,因此T这两种方法都引用相同的类型。



 类似资料:
  • 可以自动绑定泛型类吗?考虑一下: 通用接口: 长子类型: 字符串子类型: 自定义模块:公共类CustomModule扩展AbstractModule{ } 主要的 是否可以以某种方式(例如:基抽象类、反射或其他)自动绑定

  • Kotlin编译器在这里发出警告(未检查的强制转换): 据我所知,Kotlin smart cast应该知道由检查。 Java代码和编译器给出了完全相同的结果。 为了为每个实现获得正确的util类,我在伴生对象上创建了一个函数,该函数基于泛型类型T的参数为每个实现返回正确的util类,该参数扩展了a:,因此返回类型为。 但是,当我为的每个派生类编写函数体时,使用检查参数的类型,然后使用返回正确的u

  • 泛型类型 除了反省函数, Swift允许你定义自己的泛型类型. 它们是可以用于任意类型的自定义类、结构体、枚举, 和Array、Dictionary方式类型. 1. 定义泛型类型 定义一个普通的结构体 struct IntStack { var items = [Int]() mutating func push(_ item: Int) { items.appen

  • 我是Spring的新手,我正在尝试自动连接一个通用DAO。不幸的是,我遇到了一个错误。我试图根据它搜索信息,但大多数解决方案都声明使用@Qualifier注释,我认为这与我想要实现的目标背道而驰。 所以下面的一些代码(我将摆脱类参数,一旦我处理当前问题): 道 服务 和下面抛出的错误:

  • 如何将此迭代器与泛型类型一起使用?以下是我在“main”函数中尝试的方法: 结果是:<代码>无法从静态上下文引用非静态类项 结果是:<代码>无法从静态上下文引用非静态类项 结果: 编辑: 我调用的是类而不是方法。这项工作: 迭代器it=deq。迭代器(); 我认为,由于iterator()中返回的实例的类型是ListIterator,因此我需要使用该类型声明“it”。

  • 我试图实现一个接受泛型参数的函数定义,只要它扩展了另一个特定的泛型类型。简言之参数A必须扩展参数B,其中A和B都是泛型的。 下面是我的示例 用法示例如下 一些封闭的班级 和函数调用 我不想在抽象类声明中定义E,因为T已经在那里定义了。 我也试着做了以下几点: 将myList定义为接受扩展T的键 将E定义为T类型(无法找到如何指定它在函数中扩展T 但它从来都不起作用。有没有办法做到这一点?我在Sta