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