2

我正在使用 java 7,这个片段没有编译

ImmutableSortedMap<Integer, String> INT_TO_WORD =
       new ImmutableSortedMap.Builder<>(Ordering.natural())
           .put(1, "one")
           .put(2, "two")
           .put(3, "three")
           .build();

而这个确实

ImmutableSortedMap<Integer, String> INT_TO_WORD =
       new ImmutableSortedMap.Builder<Integer, String>(Ordering.natural())
           .put(1, "one")
           .put(2, "two")
           .put(3, "three")
           .build();

rhs当我在上指定类型时,为什么我需要在 上指定类型lhs?对操作员来说,还有什么<>比眼前所见更重要的吗?

4

2 回答 2

6

这不同于例如

ArrayList<String> l = new ArrayList<>();

这里new右侧是有效地创建 ArrayList。

在您的示例中,这new是创建一个完全不同的类型,即Builder并且仅在最后 anImmutableSortedMap是由该build()方法创建的。编译器无法知道 Builder<> 与您的 ImmutableSortedMap 有任何关系。

或者举一个愚蠢的例子,这可能是完全有效的:

ArrayList<String> l = new SomethingSilly<Boolean>().getArrayListOfStrings();
于 2014-12-18T22:20:06.560 回答
3

正如 Jeffrey 所指出的,Java 的类型推断有一些怪癖。只有在调用要为其分配变量的 Object 类型的构造函数时,才能使用菱形语法代替完整类型语法。

您不能以您尝试的方式使用菱形语法的原因是因为您将它与构建器对象的构造函数一起使用,而不是您将变量分配给的实际最终对象。

换句话说,这有效:

// Assigning directly to new object
ObjectInterface<Integer, String> object = new ObjectImplementation<>()

这不会:

// Assigning to the result of a method off of a different object;
// will fail without generic arguments
ObjectInterface<Integer, String> object = new ObjectInterface.Builder<>().build();

Java 的菱形语法和泛型推理不够健壮,无法弄清楚您在使用构建器做什么,可能是因为这种健壮性很难实现,因为 Java 的泛型推理必须以某种方式知道您的“构建”方法与您的构建器的通用参数。

于 2014-12-18T22:24:00.817 回答