为什么我不能将Java 7菱形语法与guava ImmutableSortedMap.Builder一起使用

时间:2014-12-18 22:14:15

标签: java java-7 guava diamond-operator

我使用的是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上指定类型? 对于<>运营商而言,还有什么比满足眼睛要多的东西。

2 个答案:

答案 0 :(得分:6)

这与例如

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

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

在您的示例中,new正在创建一个完全不同的类型,即Builder,最后只有ImmutableSortedMap方法创建build()。 编译器无法知道Builder&lt;&gt;与ImmutableSortedMap有任何关系。

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

ArrayList<String> l = new SomethingSilly<Boolean>().getArrayListOfStrings();

答案 1 :(得分: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的一般推理会不知何故必须知道你的#34; build&#34; method与您的构建器的通用参数相关联。