【发布时间】:2017-01-01 18:26:22
【问题描述】:
我正在尝试开发一个与扩展 java.util.List 的对象一起使用的类,例如 ArrayList。以下是我认为应该编译的示例(假设有必要的 import 语句):
public class MyClass<V extends List> {
V myList = new ArrayList();
MyClass<ArrayList> myinstance = new MyClass<>();
}
虽然“myinstace”没有问题,但编译器在尝试实例化“myList”时会失败:
MyClass.java:[17,16] 不兼容类型:java.util.ArrayList 不能 转换为 V
据我了解泛型,声明:
<V extends List>
暗示无论“V”是什么类型,它都必须是“List”的子类。那么,为什么我不能像上面那样实例化,有什么正确的方法可以在类中实例化一个“V”类型的对象吗?
此外,如何在类的方法中返回“V”类型的对象?
public V getSomeData(){
// How do we create our object of type "V"?
}
背景
我有一个界面,PatternElement:
public interface PatternElement<D,W> {
/**
* The data that this element contains or signifies.
* @return
*/
public D getData();
/**
* The width of this pattern element within a pattern.
* @return
*/
public W getWidth();
}
我正在尝试开发一个子类 PolyPatternElement,它本身可以包含许多“数据”和“宽度”项。我认为下面的代码会完成这个......
public class PolyPatternElement<V extends List, W extends List> implements PatternElement<V,W>{
@Override
public V getData() {
ArrayList data = new ArrayList();
return data;
}
@Override
public W getWidth() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
很遗憾,“getData”无法编译。因此,我缩小了问题范围并提出了原始问题。经过反馈,我认为更好的 PolyPatternElement 定义是:
public class PolyPatternElement<V,W> implements PatternElement<List,List>{
@Override
public List getData() {
ArrayList data = new ArrayList();
return data;
}
@Override
public List getWidth() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
这允许声明一个 PolyPatternElement 对象,其类型是我打算的任何 List 实现。
【问题讨论】:
-
如果在每种情况下都是
ArrayList,你为什么要使用通用的V? -
如果有人会选择
VLinkedList喜欢MyClass<LinkedList>怎么办?那么V myList = new ArrayList();有意义吗?V不代表(不能持有)任何列表,而是一些特定的但尚未未知的列表。 -
啊,这很有趣@Pshemo。如果我想返回这种类型的对象“V”怎么办?在我的课堂上......我添加了。
-
@Vance-Turner 正确的方法是构造函数
MyClass(V myList)并在其中设置myList。 -
我不确定您遇到了什么问题。如果您的
myList是V类型并且它包含一些实例(假设您通过构造函数MyClass(V myList)或方法setList(V myList)传递它)那么您可以创建方法,该方法也将返回此列表,如V getList(){ return myList;}。所以返回没有问题。你不能做的是使用new运算符创建V实例,或者因为我们不知道V将代表什么(更不用说泛型在运行时被删除)。
标签: java generics arraylist extends