假设我们有一个这样的类:
public class xx {
public interface Foo {
T getValue();
void setValue(T value);
}
public void resetFoos(Iterable> foos) {
for (Foo> foo : foos)
foo.setValue(foo.getValue());
}
}
它将无法编译,即使它看起来像“应该”:
xx.java:10: setValue(capture#496 of ?) in xx.Foo cannot be applied to (java.lang.Object)
foo.setValue(foo.getValue());
原因是foo没有绑定泛型类型,因此编译器不“知道”foo.getValue()的输出与foo.setValue()的输入兼容.
所以要解决这个问题,你必须创建一个新方法,只是为了在for()循环中绑定泛型类型参数:
public class xx {
public interface Foo {
T getValue();
void setValue(T value);
}
public void resetFoos(Iterable> foos) {
for (Foo> foo : foos)
this.resetFoo(foo);
}
// stupid extra method here just to bind
private void resetFoo(Foo foo) {
foo.setValue(foo.getValue());
}
}
这一直让我恼火.此外,似乎可以有一个简单的解决方案.
我的问题:为什么不应该扩展java语言以允许变量声明的泛型类型声明有什么“好”的理由?例如:
public class xx {
public interface Foo {
T getValue();
void setValue(T value);
}
public void resetFoos(Iterable> foos) {
for (Foo> foo : foos) {
final Foo typedFoo = foo;
foo.setValue(foo.getValue());
}
}
}
或者,在这种情况下更简洁的for()循环:
public class xx {
public interface Foo {
T getValue();
void setValue(T value);
}
public void resetFoos(Iterable> foos) {
for ( Foo> foo : foos)
foo.setValue(foo.getValue());
}
}
我想知道是否有一些编译器向导可以解释为什么这会太难,或者可以(并且应该)完成.
编辑:
针对此建议的解决方案:
public void resetFoos(Iterable> foos) {
for (Foo foo : foos) {
foo.setValue(foo.getValue());
}
}
此方法签名不允许将具有各种泛型类型的Foos重置在一起.换句话说,尝试传入Iterable< Foo>导致编译错误.
public static class FooImpl implements Foo {
private T value;
public FooImpl(T value) { this.value = value; }
@Override public T getValue() { return value; }
@Override public void setValue(T value) { this.value = value; }
}
public static void resetFoos(Iterable> foos) {
for (Foo foo : foos) {
foo.setValue(foo.getValue());
}
}
public static void main(String[] args) {
final Foo objFoo = new FooImpl<>(new Object());
final Foo numFoo = new FooImpl<>(new Integer(42));
final Foo strFoo = new FooImpl<>("asdf");
List> foos = new ArrayList<>(3);
foos.add(objFoo);
foos.add(numFoo);
foos.add(strFoo);
resetFoos(foos); // compile error
System.out.println("done");
}
编译错误如下:
method resetFoos cannot be applied to given types;
required: Iterable>
found: List>
reason: no instance(s) of type variable(s) T exist so that argument type List> conforms to formal parameter type Iterable>
where T is a type-variable:
T extends Object declared in method resetFoos(Iterable>)
(通过ideone.com使用sun-jdk-1.7.0_10)