泛型类型推断失败? [英] Generics type inference fails?
问题描述
示例A
请阅读以下代码片段:
public class ExampleA {
static class Pair< F,S> {}
static< F,S>对< F,S> anyPair(){return null; }
static< F,S> (Pair p1,Pair p2){return; }
public static void main(String [] args){
Pair< String,Integer> p = anyPair();
process(p,anyPair()); //不会编译
}
}
有人可以解释为什么type推理适用于赋值给局部变量 p
,但不适用于第二个实际参数<
示例B
这可能更容易理解:
public class ExampleB {
public static< E>无效过程(Set< E> s1,Set< E> s2){return; }
$ b public static void main(String [] args){
process(new HashSet< String>(),Collections.emptySet()); // does not compile
}
}
同样的问题: 't it compile?
我希望 Collections.emptySet()
只适用于 ANY 参数化 Set
类型。
到 anyPair()
没有任何方法来确定它的类型,所以它默认为< Object,Object>
。
编译器将 process
时使用它。
当它处理 anyPair()
时,没有可用的类型信息,因为它不知道它是 process
。它默认为< Object,Object>
,然后在查看 process
时导致类型不匹配。
第二个例子会发生同样的情况。 Collections.emptySet()
需要自行处理,但无法确定所需的类型。
有两种方法可以解决这个问题:
第一种方法是给编译器提供类型推断所需的信息,就像您对第一次调用<$ c
第二个(感谢@BalusC)是$ b> anyPair(),它存储在一个临时变量中。使用 ExampleA。< String,Integer> anyPair()
。该语法显式设置所需的类型,而不必超出调用范围。
Example A
Study the following snippet:
public class ExampleA {
static class Pair<F,S> { }
static <F,S> Pair<F,S> anyPair() { return null; }
static <F,S> void process(Pair<F,S> p1, Pair<F,S> p2) { return; }
public static void main(String[] args) {
Pair<String,Integer> p = anyPair();
process(p, anyPair()); // doesn't compile
}
}
Can someone explain why type inference works for the assignment to local variable p
but not for the second actual parameter to process
?
Example B
This is perhaps simpler to understand:
public class ExampleB {
public static <E> void process(Set<E> s1, Set<E> s2) { return; }
public static void main(String[] args) {
process(new HashSet<String>(), Collections.emptySet()); // doesn't compile
}
}
Same question: why doesn't it compile?
I'd hope that Collections.emptySet()
would just work for ANY parameterized Set
type.
Your second call to anyPair()
does not have any way to determine it's types and so it defaults to <Object, Object>
.
The compiler is breaking process(p, anyPair());
into it's pieces and processing each individually. When it does this, it needs to process the arguments first to determine their types, which can then be used when processing process
.
When it goes to process anyPair()
there is no type information available for that piece, because it does not know that it is part of process
at that point. It defaults to <Object, Object>
, which then causes a type mismatch when looking at process
.
The same thing happens with your second example. Collections.emptySet()
needs to be processed by itself, but has no way of determining the Types needed.
There are 2 ways to solve this:
The first is to give the compiler the information it needs for type inference the same way you did with the first call to anyPair()
, by storing it in a temporary variable with the correct type.
The second (thanks to @BalusC) is to use ExampleA.<String, Integer>anyPair()
. This syntax explicitly sets the types needed without having to look beyond the invocation.
这篇关于泛型类型推断失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!