Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java泛型,列表列表列表_Java_Generics - Fatal编程技术网

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*