在javagenerics中键入Witness
我从Geonicics Trail In Java Documentation中看到了什么Type Witness
BoxDemo.addBox(Integer.valueOf(10), listOfIntegerBoxes);
或者,如果省略类型见证,Java编译器会自动推断(从方法的参数)类型参数是Integer:
BoxDemo.addBox(Integer.valueOf(20), listOfIntegerBoxes);
想了解
- 这样做的正确方法是什么? 使用Type Witness还是让Java推断?
- 是否存在绝对需要使用类型见证的情况?
- 这是Java 5的function还是以后添加的function?
一些快速回答您的问题:
这样做的正确方法是什么? 使用Type Witness还是让Java推断?
由于这两种方法都是有效的,因此没有技术上正确的答案。 但代码可读性应始终是质量标准。 所以后者更好。 此外,您可以在开发的稍后时间更改参数的类型。 使用类型推断,您不必更改该行。
是否存在绝对需要使用类型见证的情况?
是。 当无法从方法的输入参数推断出类型时,需要它。 也许generics类型仅用于返回值,独立于参数的类型。 那么你只需要指定它。
这是Java 5的function还是以后添加的function?
generics是Java 5的语言特性。 类型推断是在JLS中指定的编译器function。 在Java 8 JLS中,这个主题有了自己的章节。 每个Java版本都对该function进行了一些增强。 例如,Java 7引入了钻石运算符。 据我所知,Java 5中已经引入了类型见证方法。
是否存在绝对需要使用类型见证的情况?
这是Java 5的function还是以后添加的function?
下面的示例显示了使用Java SE 8中提供的类型见证和改进的强制性情况
引用Generics trail Java文档:
假设您要使用空列表调用方法processStringList。 在Java SE 7中,以下语句不编译:
processStringList(Collections.emptyList());
Java SE 7编译器生成类似于以下内容的错误消息:
List
类型参数T的值,因此它以值Object开头。 因此,Collections.emptyList的调用返回List类型的值,该值与方法processStringList不兼容。 因此,在Java SE 7中,您必须指定type参数值的值,如下所示:
processStringList(Collections.emptyList());
Java SE 8中不再需要这一点。目标类型的概念已经扩展为包含方法参数,例如方法processStringList的参数。 在这种情况下,processStringList需要一个List类型的参数。 方法Collections.emptyList返回List的值,因此使用List的目标类型,编译器推断类型参数T的值为String。 因此,在Java SE 8中,以下语句编译:
processStringList(Collections.emptyList());
为了完整起见,这是在Java 5中添加的。以下是JLS第三版的相关部分,其中包括Java 5和6:
8.8.7.1显式构造函数调用
ExplicitConstructorInvocation: NonWildTypeArguments 选择此项(ArgumentList opt ); NonWildTypeArguments opt super(ArgumentList opt ); 主。 NonWildTypeArguments opt super(ArgumentList opt ); NonWildTypeArguments:ReferenceTypeList: 引用类型 ReferenceTypeList,ReferenceType
15.12方法调用表达式
的MethodInvocation: MethodName(ArgumentList opt ) 小学。 NonWildTypeArguments opt标识符(ArgumentList opt ) 超级 NonWildTypeArguments opt标识符(ArgumentList opt ) class级名称 。 超级 NonWildTypeArguments opt标识符(ArgumentList opt ) TypeName。 NonWildTypeArguments标识符(ArgumentList opt )
请注意,它们称为NonWildTypeArguments
。 术语“类型见证”未出现在JLS中。 在JLS SE 8中,重写调用规范以使用预先存在的TypeArguments
概念; 而“见证”这个词仍然无处可见。
( MethodName
已经包含TypeName.Identifier
,因此第五个方法调用定义了Type Witness的显式用法,这就是它不被标记为可选的原因。)