繁体   English   中英

需要帮助以了解有关泛型的Java教程

[英]Need help in understanding Java tutorial on Generics

我正在从这里阅读Java教程。 我在理解一条简单的线时遇到了麻烦。

教程说Collections.emptyList声明是:

static <T> List<T> emptyList();

因此,如果我们编写List<String> listOne = Collections.emptyList(); ,它的工作方式是Java编译器能够推断出type参数,因为返回的值应为List<String>类型。

现在考虑一个方法: void processStringList(List<String> stringList) 现在它说:

processStringList(Collections.emptyList()); Java SE 7编译器生成类似于以下内容的错误消息:

List <'Object>不能转换为List <'String>

编译器需要类型参数T的值,因此它以值Object开头。 因此,对Collections.emptyList的调用返回类型为List<Object>的值,该值与方法processStringList不兼容。

现在,它们的意思是: 所以它以值Object开头 我的意思是开始做什么?

基本上,这与编译器的功能有关。 换句话说:在某种程度上,可能类型推断的“数量”是一个实现细节。

在Java 7中,有时必须使用类型helper / hints / witnesses,在其中使用Collections.<String>emptyList()来告知编译器该缺失部分。

以后的编译器实现改善了您几乎总是可以使用Collections.emptyList()

关于The compiler requires a value for the type argument T so it starts with the value Object. ……实际上很简单:java编译器必须实现一种算法,最后才能推断出特定类型。 提供一些伪代码,可能类似于:

Class<?> inferType(SomeSyntaxTree construct) {

我只是在这里使用Class来表示算法将返回类似于已知类型的东西。 现在,该方法可以这样实现:

 Class<?> inferedType = Object.class
 while (whatever) {
   refine inferedType
 }
 return inferedType

换句话说:当您“搜索”某些值时,这是一种非常常见的方法:使用“最通用”值进行初始化(在Java类型系统中,它将是Object.class),然后查看该通用值可以通过应用任何算法来优化值。

在我们的例子中,优化可能最终会得出“可以使用的最特定类型是String ”的信息,但是如果无法进一步优化,则最终会出现“初始默认值”,即Object

该声明

processStringList(Collections.emptyList());

在Java 8中工作正常(我也假设在8以上)。 在这种情况下,编译器足够聪明,可以通过检查方法的预期参数类型来推断类型。

在旧版本中,当编译器看不到显式的返回类型时(如List<String> listOne = Collections.emptyList(); ),默认情况下它将<T>推断为java.lang.Object 但是请注意, List<Object>List<String>不兼容。

您可以将方法声明为void processString(List<? super String> list)以避免发生错误。

暂无
暂无

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

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