![](/img/trans.png)
[英]How does java compiler know of generics type information of a code in jar?
[英]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 stringElement
是Object
的子类,因此允许这样做。
在第二种情况下,您要将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.