繁体   English   中英

编译器如何推断Java泛型中的类型

[英]how compiler infers the type in java generics

我有看起来像这样的通用方法。

public static <T> T addAndReturn(T element, Collection<T> collection){
    collection.add(element);
    return element;
}

当我打电话

String stringElement = "stringElement";
List<Object> objectList = new ArrayList<Object>();
Object theElement = addAndReturn(stringElement, objectList); 

它将类型推断为对象。

当我打电话

Object objectElement = new Object();
List<String> stringList = new ArrayList<String>();
Object theElement = addAndReturn(objectElement, stringList);

编译器报告错误。

这背后的规则是什么?

在第一种情况下,您要将List<Object>传递给Collection<T>因此T必须是Object类型。 String stringElementObject的子类,因此允许这样做。

在第二种情况下,您要将List<String>传递给Collection<T>因此T只能是String 由于Object objectElement不是String类型,因此不允许这样做。

您不能将Object添加到似乎合理的List<String>中。

泛型可能很难掌握,我建议您仔细阅读。

在您的示例中,您有一个T类型,它可以是任何一种类型。 此类型是“泛型”的,因为它符合放入其中的类型。 因此,当您将ArrayList<String>作为Collection<T>参数传递时, T在该实例中成为String 因此,该方法的返回类型为String

泛型根据类型推断原理工作。 编译器检查泛型类中的类型。 确定类型后,编译器将执行编译时类型检查,以确保传递的所有类型都是正确的。 泛型在运行时也具有类型擦除,但这是另一回事,在本讨论中我们可以跳过它。

在您的问题上应用此原理:在第一种情况下,您将创建一个String类型的对象,由于String是Object的子类,因此可以轻松地将其添加到Object类型的ArrayList中。

对于第二个示例,您现在正好相反。 您正在尝试将Object类对象保存在不允许的String类的引用中。

因此,即使您注意到规则,也与非通用代码完全相同。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM