java - 用于 Java 中看起来很奇怪的显式类型参数声明语法

标签 java generics syntax types

我最近遇到了在调用 Java 方法时显式声明泛型类型的奇怪语法。例如:

Collections.<String>emptyList();

返回一个空的 List<String> .但是,这似乎很愚蠢,因为 <T> emptyList() 的实现只是未经检查的类型转换 (List<T>) EMPTY_LIST ,这样所有结果都具有相同的类型删除(并且是相同的对象)。此外,通常不需要这种显式类型声明,因为编译器通常可以推断出类型:

List<String> empty = Collections.emptyList();

在做了更多挖掘之后,我发现另外两次你想要使用这种语法,它们都是由于使用了 Guava 库并且显然试图在一行中放置太多语句.

  1. 装饰集合,例如使用同步包装器,而编译器无法推断类型。如果您取出类型声明,以下内容将不起作用:cannot convert from Set<Object> to Set<String> :

    Set<String> set = Collections.synchronizedSet(Sets.<String>newHashSet());
    
  2. 当编译器试图生成过于具体的类型参数时,获得不太具体的类型参数。例如,如果没有类型声明,以下语句也会报错:cannot convert from Map<String, String> to Map<String, Object> :

    Map<String, Object> toJson = ImmutableMap.<String, Object>of("foo", "bar");
    

我觉得具有讽刺意味的是,在第一种情况下,推断的类型参数过于笼统,而在第二种情况下,它们又过于具体,但我认为这只是 Java 中泛型系统的产物。

但是,除了这些 strange use cases invented by the Guava team 之外,这种语言结构本身似乎是可以避免的。 .此外,在我看来, 编译器可以在上述两个示例中推断类型参数,但开发人员只是选择不这样做。是否有示例表明在 Java 编程中使用此构造是必要的或有用的,还是它的存在仅仅是为了使编译器更简单/JDK 开发人员的生活更轻松?

最佳答案

为什么“关闭编译器”不是“必要的或有用的”?我发现它对于我的代码编译来说既是必要的又是有用的。

正如您已经发现的那样,有时无法推断出正确的类型。在这种情况下,有必要explicitly specify the type parameters .编译器不够智能的一些示例:

如果您真的想深入研究类型推断的复杂性,它从 Java 语言规范开始和结束。您需要关注 JLS §15.12.2.7. Inferring Type Arguments Based on Actual Arguments§15.12.2.8. Inferring Unresolved Type Arguments .

关于java - 用于 Java 中看起来很奇怪的显式类型参数声明语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15629552/

相关文章:

Mysql 子查询语法

java - 为什么这个 Spring AOP 切入点没有被触发?

macos - 适用于 Mac/Windows 的 Java 7 安装程序

java - 我的 pom.xml 包含此 maven-formatter-plugin,但未构建。我需要定义格式目标吗?

c++ - 可能有一个函数可用于泛型类中的一种类型?

java - <? 之间的区别扩展 CustomClass> 和 <CustomClass> 通用性

具有参数化类型的 Java getConstructor(types)

javascript - jQuery 切换隐藏速度这么快?

java - 我的 java 代码有一个明显的错误。为什么它会编译和运行?

java - Mybatis 结果声明重用