考虑以下简单代码
import java.util.*;
public class MainTest<T extends Object1<?,?>> {
List<T> list;
public MainTest(List<T> l) {
this.list=l;
}
public int testCompare() {
// fails to compile here
return list.get(0).compareTo(list.get(1));
}
public static void main(String[]args) {
List<Object1Impl> list = new ArrayList<Object1Impl>();
list.add(new Object1Impl());
list.add(new Object1Impl());
MainTest<Object1Impl> test = new MainTest<Object1Impl>(list);
System.out.println(test.testCompare());
}
}
interface Object1<E, V> extends Comparable<Object1<E,V>> { }
class Object1Impl implements Object1<Integer, Integer>{
public int compareTo(Object1<Integer, Integer> o) { return 0; }
}
我知道在这种情况下程序不会编译(在testCompare()失败,因为T正在扩展无界Object1<?,?>
)。除了制作MainTest<T extends Object1<E,V>,E,V>
之外,还有其他方法可以解决这个问题吗?
编辑:错误消息是
The method compareTo(Object1<capture#1-of ?,capture#2-of ?>) in the type Comparable<Object1<capture#1-of ?,capture#2-of ?>> is not applicable for the arguments (T)
我读过有效的Java书,但仍然无法真正想到解决方案..
另外,为什么如果我将接口Object1更改为抽象类,程序将编译没有任何问题?这真让我感到困惑......
编辑:当我的意思是改为抽象类时如下
abstract class Object1<E, V> implements Comparable<Object1<E,V>>{
public int compareTo(Object1<E,V> o) { return 0; }
}
class Object1Impl extends Object1<Integer, Integer>{ }
这将有效(只有使用Eclipse,使用javac手动编译它不起作用)但我不知道为什么
答案 0 :(得分:4)
这是正确的;编译器无法验证list.get(0)
和list.get(1)
是否属于同一类型;一个可能是Object1<String, Integer>
而另一个Object1<BigDecimal, Double>
。
要确保它们属于同一类型,您必须绑定这些类型:
public class MainTest<A,B,T extends Object1<A,B>> {
List<T> list;
public MainTest(List<T> l) {
this.list=l;
}
public int testCompare() {
// fails to compile here
return list.get(0).compareTo(list.get(1));
}
public static void main(String[]args) {
List<Object1Impl> list = new ArrayList<Object1Impl>();
list.add(new Object1Impl());
list.add(new Object1Impl());
MainTest<Integer, Integer, Object1Impl> test = new MainTest<Integer, Integer, Object1Impl>(list);
System.out.println(test.testCompare());
}
}
据我所知,Java不允许将参数类型绑定到类而没有特别指定它们。