Java泛型,列表列表列表
这件事把我难住了。我的课程如下:Java泛型,列表列表列表,java,generics,Java,Generics,这件事把我难住了。我的课程如下: public class SpecialList implements List<MyType> { // overriden methods } 公共类SpecialList实现列表{ //重写方法 } 现在,我在更高级别上需要遵守以下方法合同: public class MyClass { private List<SpecialList> bigList = new ArrayList<SpecialLis
public class SpecialList implements List<MyType> {
// overriden methods
}
公共类SpecialList实现列表{
//重写方法
}
现在,我在更高级别上需要遵守以下方法合同:
public class MyClass {
private List<SpecialList> bigList = new ArrayList<SpecialList>();
public void doStuff(List<MyType> list)
{
bigList.add((SpecialList)list); // does not compile - invalid cast
}
}
公共类MyClass{
private List bigList=new ArrayList();
公共作废文件(列表)
{
bigList.add((SpecialList)list);//未编译-无效强制转换
}
}
我真的不确定我在这里做错了什么。我有一个实现列表
接口的类,但我不能将该类强制转换为列表
?那对我来说毫无意义
我迷路了。我该怎么做才能让这一切顺利?我想这与泛型协方差有关,但在这一点上我不知道这里出了什么问题。有人能指出正确的方向吗?谢谢。您定义了列表
(即我的列表
)。这意味着您只能添加MyList
的实例。如果使用的是addAll()
,则可以添加MyList的列表。但是您正在尝试添加列表
MyType
绝对不是MyList
显然,您不能将List
转换为MyList
并非每个列表
(动物)都是我的列表
(奶牛)
您正在将动物添加到奶牛列表中据我所知,类型转换列表的正确方法是使用泛型。比如:
bigList.add((List<MyList>)(List<?>)list);
bigList.add((List)(List)List);
但是,我不确定这段代码背后的理论。为什么会发生这种错误
代码在形式上是正确的。您可以将几乎任何对象强制转换为任何其他对象,代码将编译。如果强制转换无效,将引发运行时ClassCastException
您的IDE可以在编译时检测不确定的强制转换并对其进行投诉。要么作为警告,要么作为错误。这是一个配置问题。显然,OPs IDE被配置为使这样的代码嗅到编译错误
为什么这个石膏不安全
您可以回答以下问题:
您能否创建一个非特殊列表的列表
您不能将列表
强制转换为特殊列表
,因为可能存在将成为列表
的对象,而实际上不是特殊列表
解决
更改应用程序架构
您可以做两件事-使用类specialist
all accross-your-code,或者使用通用列表
换句话说,要么改变:
doStuff(列表)
至doStuff(特殊列表)
或者改变
private List bigList
到private List bigList
您必须决定是要在任何地方使用通用接口列表还是您自己的类。请记住,您可以始终将specialist
强制转换为List
,因为所有specialist
实例也是List
的实例。相反,它不起作用
确保演员阵容始终有效
如果您一定要使此设计正常工作,请使用instanceof检查列表是否真的是一个特殊列表
。就像这样:
public void doStuff(List<MyType> list)
{
if (list instanceof SpecialList) {
bigList.add((SpecialList)list);
} else {
SpecialList sl = new SpecialList(list); // I hope you have that constructor
bigList.add(sl);
}
}
public void doStuff(列表)
{
if(列出SpecialList的实例){
添加((SpecialList)列表);
}否则{
specialist sl=new specialist(list);//我希望您有那个构造函数
添加(sl);
}
}
这在我的Eclipse中有效,这是SpecialList类,Hello是MyType类
package a;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class SpecialList implements List<Hello> {
//Overridden methods
}
a包;
导入java.util.Collection;
导入java.util.Iterator;
导入java.util.List;
导入java.util.ListIterator;
公共类SpecialList实现列表{
//重写的方法
}
这是我的班级
package a;
import java.util.ArrayList;
import java.util.List;
public class MyClass {
private List<SpecialList> bigList = new ArrayList<SpecialList>();
public void doStuff(List<Hello> list)
{
bigList.add((SpecialList)list); //compiles good
}
public static void main(String[] args) {
new MyClass().doStuff(null);
}
}
a包;
导入java.util.ArrayList;
导入java.util.List;
公共类MyClass{
private List bigList=new ArrayList();
公共作废文件(列表)
{
添加((SpecialList)列表);//编译良好
}
公共静态void main(字符串[]args){
新建MyClass().doStuff(null);
}
}
没有编译时错误或运行时异常我建议使用一些参数:
public class MyClass{
private List<List<MyType>> bigList = new ArrayList<List<MyType>>();
public <E extends List<MyType>> void doStuff(E list)
{
bigList.add(list);
}
}
公共类MyClass{
private List bigList=new ArrayList();
公共垃圾收集站(E列表)
{
添加(列表);
}
}
但是,当您从bigList中检索元素时,您不能专门化该元素,因为它来自泛型列表。
如果您确实需要强制转换它,可能您的类体系结构不正确。
或者你可以滥用这种方式:
public class MyClass{
private List<List<MyType>> bigList = new ArrayList<List<MyType>>();
public <E extends List<MyType>> void doStuff(E list)
{
bigList.add(list);
}
public <E extends List<MyType>> E getStuff(Class<E> myType,int i)
{
List<MyType> obj = bigList.get(i);
if(myType.isInstance(obj)) return (E) obj;
throw new SomeErrorHere("invalid type for index");
}
}
公共类MyClass{
private List bigList=new ArrayList();
公共垃圾收集站(E列表)
{
添加(列表);
}
公共E getStuff(类myType,int i)
{
List obj=bigList.get(i);
if(myType.isInstance(obj))返回(E)obj;
在此处抛出新的someError(“索引的类型无效”);
}
}
列表与列表不同。
让我们简单一点,看下面几行:
*List<MyList> myList = new ArrayList<MyList>(); //1
myList.add(new MyType);//2 ......Compile ERROR*
*List myList=new ArrayList()//1.
添加(新的MyType)//2……编译错误*
如果您试图将MyType实例添加到列表中
,则会出现错误
为什么?
- 泛型表示参数化类型李>
- 泛型添加类型安全性李>
- 这意味着,对于泛型,所有类型转换都是自动和隐式的,
它们不需要在添加和检索对象时进行类型转换
从列表中明确列出
实时场景:
如果机动车辆部提供驾驶员名单。
我们认为列表
是列表
,假设驾驶员是人的一个子类型
如果是这样的话,我们可以把不是司机的人加入名单
那就是所有的人都是N
*List<MyList> myList = new ArrayList<MyList>(); //1
myList.add(new MyType);//2 ......Compile ERROR*