Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.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_Generic List - Fatal编程技术网

Java泛型列表返回类型

Java泛型列表返回类型,java,generics,generic-list,Java,Generics,Generic List,我对返回泛型列表的方法有一些问题。代码基本上是这样的: public class MyClass{ private List<MyListElement> myList = new ArrayList<MyListElement>(); public <E> List<E> getGenericList(){ return new ArrayList<E>(); } public vo

我对返回泛型列表的方法有一些问题。代码基本上是这样的:

public class MyClass{
    private List<MyListElement> myList = new ArrayList<MyListElement>();

    public <E> List<E> getGenericList(){
        return new ArrayList<E>();
    }

    public void thisWorks(){
        List<MyListElement> newList = getGenericList();
        myList.addAll(newList);
    }

    public void thisDoesntWork(){
        myList.addAll(getGenericList());
    }

    public void thisDoesntWorkEither(){
        for(MyListElement elem : getGenericList()){
            fiddle();
        }
    }
}
公共类MyClass{
private List myList=new ArrayList();
公共列表getGenericList(){
返回新的ArrayList();
}
公共工程(){
List newList=getGenericList();
myList.addAll(newList);
}
公共无效ThisDoesNetwork(){
addAll(getGenericList());
}
public void this doesntworkeither(){
对于(MyListElement元素:getGenericList()){
小提琴();
}
}
}

为什么
ThisDoesNetwork()
方法不起作用,还有其他方法吗(除了用不总是实用的
thisWorks()
方法之外)?

您可以这样更改
ThisDoesNetwork()

  public void thisDoesntWork(){ // well, it works now
      myList.addAll(this.<String>getGenericList());
  }
public void this doesnetwork(){//好吧,它现在可以工作了
myList.addAll(this.getGenericList());
}

您需要告诉编译器正在处理什么类型的
getGenericList()

编译器无法推断要为
ThisDoesNetwork()
中的泛型方法
getGenericList()
的类型参数
选择什么类型

在这种情况下,需要通过调用
getGenericList()

或者,您可以更改
getGenericList()
的签名以接受
Class
参数。然后在
thisWorks()
ThisDoesNetwork()中调用
getGenericList(MyListElement.class)
。诚然,这有点冗长,但对您的方法的客户来说更直观


我想说,作为一般规则,尝试使泛型方法的类型参数可以从该方法的参数推断出来。

泛型方法的类型参数
getGenericsList()
可以在调用时传递:

this.<String>getGenericsList()
编译器似乎无法推断正确的类型,老实说,我不知道这是因为它不够聪明,还是因为它不想通过设计承担责任

我甚至做了一个测试,看看问题是否出在通配符上,或者
addAll()
是否无法从参数化类型推断类型参数,但似乎什么都不起作用:

公共类泛型列表{
公共静态void main(字符串[]args){
//与JavaAPI相同的签名
列表基=新列表();
base.addAll(GenericsList.getList());//错误!
//addAll()不使用通配符
List2 base2=新的List2();
base2.addAll(getList2());//错误!
//通用方法呢?
addAll(base,getList());//错误!
}
静态列表getList(){
返回新列表();
}
静态void addAll(List src,List other){}
静态列表2 getList2(){
返回新的List2();
}
静态类列表{

void addAll(List此代码适用于您。
getGenericList()
应该知道它返回什么,并且应该与您的列表类型兼容

您不需要将其强制转换为字符串或其他人建议的任何其他类型,因为它会通过将其绑定到字符串类型来限制getGenericList方法的意图。

public class MyClass{
    private List<MyListElement> myList = new ArrayList<MyListElement>();

    public <E extends MyListElement> List<E> getGenericList(){
        return new ArrayList<E>();
    }

    public void thisWorks(){
        List<MyListElement> newList = getGenericList();
        myList.addAll(newList);
    }

    public void thisDoesntWork(){
        myList.addAll(getGenericList());
    }

    public void thisDoesntWorkEither(){
        for(MyListElement elem : getGenericList()){
            fiddle();
        }
    }
}
公共类MyClass{
private List myList=new ArrayList();
公共列表getGenericList(){
返回新的ArrayList();
}
公共工程(){
List newList=getGenericList();
myList.addAll(newList);
}
公共无效ThisDoesNetwork(){
addAll(getGenericList());
}
public void this doesntworkeither(){
对于(MyListElement元素:getGenericList()){
小提琴();
}
}
}

当它不实用时,意味着您不应该这样做。即使您的
thisWorks
方法也不安全,因为您假设您的
genericList
将保留
字符串(您无法从代码中确定)。getGenericList()返回一个列表,但您需要调用addAll()使用列表。列表与列表不同,因此会出现错误。那么为什么myList会声明为列表而不是列表呢?@SJuan76:没有办法。原始数据源包含对象,但我们需要能够将内容视为字符串。这在理论上可能会导致ClassCastException是的,但希望我们能够保留它检查包含什么类型的列表。从
对象
字符串
的传递通常使用
toString()
完成。只是说这是一个很好的观点,但字符串只是一个示例。我还需要能够处理其他类型。在任何情况下,如果元素实际上不是字符串,则添加toString()的结果与ClassCastException相比,添加到列表中可能会导致更多的混乱。我编辑了这个问题,以反映它实际上与字符串无关。当泛型列表不包含字符串时会发生什么?因为
myList
需要
String
,我们知道我们正在处理
String
s。如果它是其他类型,代码必须相应地更改。getGenericList()只是一个尽可能简化代码的示例方法。在实际应用程序中,它将返回一个实际列表,理论上,其中的对象可能是其他类型。我假设结果是ClassCastException。@jahroy:它不包含任何内容,但这与此无关。我们正试图告诉编译器要推断的类型
E
@jahroy:我们不是在讨论运行时(在运行时,不同类型的列表之间没有区别)。我们是在讨论编译时。在编译时,每个表达式都有一个由编译器推断的特定类型。可以同时使用getGenericList()和getGenericList(类)吗版本?这会让打电话的人选择他想要使用的版本。你能解释一下我们如何添加stri列表吗
public class MyClass{
    private List<MyListElement> myList = new ArrayList<MyListElement>();

    public <E extends MyListElement> List<E> getGenericList(){
        return new ArrayList<E>();
    }

    public void thisWorks(){
        List<MyListElement> newList = getGenericList();
        myList.addAll(newList);
    }

    public void thisDoesntWork(){
        myList.addAll(getGenericList());
    }

    public void thisDoesntWorkEither(){
        for(MyListElement elem : getGenericList()){
            fiddle();
        }
    }
}