And*_*Mao 14 java generics syntax types
我最近发现了在调用Java方法时显式声明泛型类型的奇怪语法.例如:
Collections.<String>emptyList();
Run Code Online (Sandbox Code Playgroud)
返回一个空的List<String>.但是,这看起来很愚蠢,因为实现<T> emptyList()只是未经检查的类型转换(List<T>) EMPTY_LIST,因此所有结果都具有相同的类型擦除(并且是相同的对象.)此外,通常不需要这种显式类型声明,因为编译器通常可以推断类型:
List<String> empty = Collections.emptyList();
Run Code Online (Sandbox Code Playgroud)
在做了一些挖掘之后,我发现了另外两次你想要使用这种语法,并且它们都是由于使用了Guava库并且显然试图在一行上放置太多语句.
装饰集合,例如使用同步包装器,并且编译器无法推断类型.如果您取出类型声明,则以下内容不起作用cannot convert from Set<Object> to Set<String>:
Set<String> set = Collections.synchronizedSet(Sets.<String>newHashSet());
Run Code Online (Sandbox Code Playgroud)在编译器尝试创建过于具体的类型参数时,获取较少的特定类型参数.例如,如果没有类型声明,以下语句也会抱怨cannot convert from Map<String, String> to Map<String, Object>:
Map<String, Object> toJson = ImmutableMap.<String, Object>of("foo", "bar");
Run Code Online (Sandbox Code Playgroud)我觉得具有讽刺意味的是,在第一种情况下,推断类型参数过于笼统,在第二种情况下它们过于具体,但我认为这只是Java中泛型系统的一个工件.
然而,除了在番石榴团队发明的这些奇怪的用例之外,这种语言结构本身似乎是可以避免的.此外,看似平淡,我认为那里是编译器推断类型参数同时在上面的例子中的方式,而开发商只是选择不这样做.是否有在Java编程中使用此构造所必需或有用的示例,还是仅仅为了使编译器更简单/ JDK开发人员的生活更容易存在?
如何"关闭编译器"不是"必要或有用的"?我发现编译代码既有必要又有用.
有些时候,正如您已经发现的那样,无法推断出正确的类型.在这种情况下,有必要明确指定类型参数.编译器的一些例子不够智能:
如果您真的想深入了解类型推断的复杂性,它将以Java语言规范开始和结束.您将要关注JLS§15.12.2.7.根据实际参数和§15.12.2.8推断类型参数.推断未解决的类型参数.