在下面的示例中,为什么编译器能够推断第一次调用Foo.create()in 的泛型参数Foo.test(),但在第二次调用时却无法这样做?我正在使用Java 6.
public class Nonsense {
public static class Bar {
private static void func(Foo<String> arg) { }
}
public static class Foo<T> {
public static <T> Foo<T> create() {
return new Foo<T>();
}
private static void test() {
Foo<String> foo2 = Foo.create(); // compiles
Bar.func(Foo.create()); // won't compile
Bar.func(Foo.<String>create()); // fixes the prev line
}
}
}
Run Code Online (Sandbox Code Playgroud)
(编译错误是Nonsense.Bar类型中的方法func(Nonsense.Foo)不适用于参数(Nonsense.Foo)).
注意:我理解编译器错误可以通过test()中的第三行修复 - 我很好奇是否存在阻止编译器推断类型的特定限制.这似乎对我有足够的上下文在这里.
研究以下片段:
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
}
}
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么类型推断适用于局部变量的赋值p但不适用于第二个实际参数process吗?
这可能更容易理解:
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 …Run Code Online (Sandbox Code Playgroud) 我有一个关于接口中正确方法签名的问题,以及为什么。我的事件是用一个类型参数化的,但是接口也应该有一个<T>在方法签名中使用它的吗?如果是为什么,为什么不呢?
public interface MyListener {
void beforeAction(final MyEvent event);
}
Run Code Online (Sandbox Code Playgroud)
和
public class MyEvent<T> extends EventObject {
// code
}
Run Code Online (Sandbox Code Playgroud)