2

我有一个这样的列表结构设置:

List<List<Value>> l = new RowList();

这给出了一个"Type mismatch: Cannot convert from RowList to List<List<Value>>"错误。实现如下:

public class RowList extends ArrayList<ValueList>
public class ValueList extends ArrayList<Value>

值是我代码库中的一个对象。为什么这不起作用?当我有这个时,一切正常:

public class RowList extends ArrayList<List<Value>>

对于我正在处理的大学作业,我们的讲师编写的代码通过调用List<List<Value>>在我的代码中返回 a 的方法来工作,然后添加List<Value>到该列表中。由于该程序旨在实现数据库,因此有许多要求,例如键值不出现多次等。为了检查这没有发生,我需要能够拥有一个 ValueList 类或类似的东西所以我可以扩展add()方法来检查这些要求。

现在听起来这不是正确的做事方式,但我真的没有任何选择,因为我们不允许更改执行此操作的代码。我相信这个想法是它让我们思考泛型。

4

2 回答 2

8

首先创建集合的子类是个坏主意。坚持标准实现,使用组合而不是继承。

现在要了解为什么这不能编译,这就是为什么,用一个简短的例子。假设您想做的事情是可能的并且可以编译,那么您可以执行以下操作:

RowList rowList = new RowList();
List<List<Value>> listOfLists = rowList;
listOfLists.add(new LinkedList<Value>());

尽管 RowList 应该ValueList只包含 的实例,但您将拥有一个LinkedList<Value>内部实例,从而破坏程序的类型安全性和正确性。

于 2013-05-24T07:59:40.573 回答
1

问题是,RowList不是 a List<List<Value>>,所以这List<List<Value>> l = new RowList();是无效的

就像你不能这样做:

List<Object> objList = new ArrayList<String>();

有几种选择供您选择:

将 l 的声明更改为 List:

List<ValueList> l = new RowList();

或使用通配符:

List<? extends List<Value>> l = new RowList();

编辑:虽然可以通过上述方法解决,但应该更好地重构您的设计。我认为您正在尝试使用继承来做类似typedefC/C++ 中的事情,但是使用继承来模拟 typedef 的副作用很大(至少在 Java 中),在这样做之前您应该三思而后行。我并不是说如果它真的有意义就不要使用继承(即你真的想要ValueListis-a List<ValueList>)。但是,在我看来,您这样做只是为了节省您的打字List<Value>时间,而不是引入有意义的类型。

于 2013-05-24T09:36:59.033 回答