我发现了一些对我很有趣的东西。请考虑以下代码:
// file: example.java
interface Interface1
{
Iterator<Interface2> getIterator();
}
interface Interface2
{
}
interface Interface3 extends Interface2
{
}
class Class1 implements Interface1
{
Iterator<Interface3> getIterator(); // Compiler throws error: type mismatch
}
我的问题是:
答案 0 :(得分:4)
是的,这是在某处记录的,即the Java Tutorial about generics。它也是有目的的。
如果B
是A
的子类型,那么SomeClass<B>
不是SomeClass<A>
的子类型。原因如下。假设以下代码将编译:
public static void main(String[] args)
{
ArrayList<B> list = new ArrayList<>();
// if ArrayList<B> would be a subtype of ArrayList<A>
// this would be legal:
ArrayList<A> list2 = list;
A element = new A();
list2.add(element);
// Uh-oh. Now list contains non-B elements.
B b = list.get(0); // <--- ClassCastException
}
然后可以绕过type参数并将非B对象添加到B列表中。为了解决这个问题,Java提供了绑定类型变量:类型变量可以通过extends
和super
关键字在上下绑定。有关如何使用它们的信息,请参阅Java Turorial。
答案 1 :(得分:2)
首先要实现和接口你必须使用implements not extends。其次,当使用泛型时,您可以使用扩展。
在界面中,您已经定义了一个方法,可以为您提供Iterator<Interface2> getIterator();
,但在您正在执行的实现中Iterator<Interface3> getIterator();
哪些不起作用你可以做的是使用这样的泛型(已验证不会给出编译错误):
interface Interface1
{
Iterator<? extends Interface2> getIterator();
}
interface Interface2
{
}
interface Interface3 extends Interface2
{
}
class Class1 implements Interface1
{
public Iterator<Interface3> getIterator(){
return null;
}
}
答案 2 :(得分:1)
您已实施Interface1
,其getIterator()
方法返回Iterator<Interface2>
。这意味着您的实现类需要其getIterator()
方法来返回Iterator<Interface2>
类型的内容;你要归还Iterator<Interface3>
类型的东西。
您遇到的根本问题是虽然Interface3
扩展了Interface2
,但这并不意味着Iterator<Interface3>
是Iterator<Interface2>
的子类型。不幸的是,子类化机制无法“透视”来输入参数。
它有令人讨厌的后果。例如,你不能写
List<List<String>> list = new ArrayList<ArrayList<String>>();
它会给你一个编译器错误,因为右边的表达式与左边的形式类型参数不是赋值兼容的。
虽然ArrayList<String>
是List<String>
的子类型,但ArrayList<ArrayList<String>>
不是List<List<String>>
的子类型。你有类似的事情发生在这里。