在java泛型中键入Witness

时间:2014-07-24 11:15:17

标签: java generics

我理解Type Witness是什么,正如我在Java文档中的Generics Trail中看到的那样

BoxDemo.<Integer>addBox(Integer.valueOf(10), listOfIntegerBoxes);
  

或者,如果省略类型见证,Java编译器   自动推断(来自方法的参数)该类型   参数是整数:

BoxDemo.addBox(Integer.valueOf(20), listOfIntegerBoxes);

想了解

  • 这样做的正确方法是什么?使用Type Witness或让Java推断?
  • 是否存在绝对需要使用类型见证的情况?
  • 这是Java 5的功能还是以后添加的?

3 个答案:

答案 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,因此第五个方法调用定义了类型见证的显式用法,这就是它未标记为可选的原因。)