此代码在Java 8中编译,但无法在Java 7中编译:
class Map<K,V> {
static <K,V> Map<K,V> empty() {return null;}
Map<K,V> put(K k, V v) {return null;}
V get(K k) {return null;}
}
class A {
static void f(Map<Integer,String> m){}
public static void main(String[] args) {
f(Map.empty());
}
}
它不会推断从Map
返回的Map.empty()
的具体类型:
$ javac7 A.java
A.java:10: error: method f in class A cannot be applied to given types;
f(Map.empty());
^
required: Map<Integer,String>
found: Map<Object,Object>
reason: actual argument Map<Object,Object> cannot be converted to Map<Integer,String> by method invocation conversion
1 error
如果您将f
调用更改为f(Map.<Integer,String>empty());
,则会进行编译。在Java 8中,它无需借助于此工作。
但是,如果将f
调用更改为f(Map.empty().put(1,"A").put(2,"B"));
,则无法再次编译Java 7和8.为什么?
$ $javac7 A.java
A.java:10: error: method f in class A cannot be applied to given types;
f(Map.empty().put(1,"A").put(2,"B"));
^
required: Map<Integer,String>
found: Map<Object,Object>
reason: actual argument Map<Object,Object> cannot be converted to Map<Integer,String> by method invocation conversion
1 error
$ $javac8 A.java
A.java:10: error: incompatible types: Map<Object,Object> cannot be converted to Map<Integer,String>
f(Map.empty().put(1,"A").put(2,"B"));
^
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
1 error
$ $javac8 -Xdiags:verbose A.java
A.java:10: error: method f in class A cannot be applied to given types;
f(Map.empty().put(1,"A").put(2,"B"));
^
required: Map<Integer,String>
found: Map<Object,Object>
reason: argument mismatch; Map<Object,Object> cannot be converted to Map<Integer,String>
1 error
答案 0 :(得分:31)
为什么?
因为泛型类型的类型推断尚未扩展为链式调用。
来自java tutorial on generics type inference:
什么是目标类型的概念已经扩展到包括方法参数。
这就是为什么这段代码:
f(Map.empty());
编译。
但是这段代码并不是因为这是一个链式调用:
f(Map.empty().put(1,"A").put(2,"B"));
您还可以在JSR-000335 Lambda Expressions for the JavaTM Programming Language Final Release for Evaluation(特别是D部分)中找到一个小段落:
有一些兴趣允许在a()。b()中推断&#34; chain&#34;:,将类型信息从b的调用传递给a的调用。这为推理算法的复杂性增加了另一个维度,因为部分信息必须在两个方向上传递;只有当a()的返回类型的擦除对于所有实例化(例如List)都是固定的时,它才有效。此特征不适合多聚表达模型,因为目标类型不能轻易导出;但也许还有其他增强功能,可以在将来添加。
也许在Java 9中。
答案 1 :(得分:0)
What is the type of Map.Entry.comparingByValue().reversed()?-回答这个问题更简单。
unSortedMap.entrySet().stream()
.filter(e -> e.getValue() > 1)
.sorted(Entry.comparingByValue(Comparator.reverseOrder()))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue,
(e1, e2) -> e1, LinkedHashMap::new));