java Java泛型列表返回类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13922370/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java generic list return type
提问by MatsT
I'm having some problems with a method returning a generic list. The code is basically this:
我在返回通用列表的方法方面遇到了一些问题。代码基本上是这样的:
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();
}
}
}
Why does the thisDoesntWork()
method not work, and is there any other way around it (other than doing it the thisWorks()
way which isn't always practical)?
为什么该thisDoesntWork()
方法不起作用,还有其他方法可以解决thisWorks()
吗(除了以并不总是实用的方式进行操作)?
回答by bowmore
The compiler cannot infer what type to choose for the type parameter <E>
of the generic method getGenericList()
in thisDoesntWork()
.
编译器不能推断出什么类型为类型参数选择<E>
的一般方法getGenericList()
在thisDoesntWork()
。
In this case you need to explicitly state the Type for the type argument by calling <MyListElement>getGenericList()
在这种情况下,您需要通过调用显式声明类型参数的类型 <MyListElement>getGenericList()
Alternatively you can change the signature of getGenericList()
to accept a Class<E>
argument. Then you would invoke getGenericList(MyListElement.class)
in both thisWorks()
and thisDoesntWork()
. Admittedly that's a bit more verbose, but definitly more intuitive to clients of your method.
或者,您可以更改 的签名getGenericList()
以接受Class<E>
参数。然后,你将调用getGenericList(MyListElement.class)
两个thisWorks()
和thisDoesntWork()
。诚然,这有点冗长,但对于您的方法的客户来说绝对更直观。
I would say as a general rule, try to make the type arguments of your generic methods be inferrable from that method's arguments.
我会说作为一般规则,尝试使泛型方法的类型参数可以从该方法的参数中推断出来。
回答by GriffeyDog
You can change thisDoesntWork()
like so:
你可以thisDoesntWork()
像这样改变:
public void thisDoesntWork(){ // well, it works now
myList.addAll(this.<String>getGenericList());
}
You need to tell the compiler what type getGenericList()
is dealing with.
您需要告诉编译器getGenericList()
正在处理什么类型。
回答by Raffaele
The type argument to the generic method <E> getGenericsList()
can be passed at call time:
泛型方法的类型参数<E> getGenericsList()
可以在调用时传递:
this.<String>getGenericsList()
otherwise the compiler does its best to deduce it from the context. When you assign the returned object to a List<String>
reference, the compiler hence infers that you passed String
as the type argument.
否则编译器会尽力从上下文中推断出来。当您将返回的对象分配给List<String>
引用时,编译器因此推断您String
作为类型参数传递。
Given the List API:
鉴于列表 API:
List<E> {
void addAll(Collection<? extends E> c);
}
the compiler doesn't seem to be able to infer the correct type, and to be honest I don't know if this is because it is not smart enough, or because it doesn't want to carry the responsibilityby design.
编译器似乎无法推断出正确的类型,老实说我不知道这是因为它不够聪明,还是因为它不想按设计承担责任。
I even made a test to see if the problem is the wildcard, or if addAll()
cannot infer the type arguments from the parameterized type, but nothing seems to work:
我什至做了一个测试,看看问题是否是通配符,或者是否addAll()
无法从参数化类型推断类型参数,但似乎没有任何效果:
public class GenericsList {
public static void main(String[] args) {
// same signature as Java API
List<String> base = new List<String>();
base.addAll(GenericsList.getList()); // ERROR!
// addAll() doesn't use a wildcard
List2<String> base2 = new List2<String>();
base2.addAll(getList2()); // ERROR!
// what about a generic method?
addAll(base, getList()); // ERROR!
}
static <E> List<E> getList() {
return new List<E>();
}
static <E> void addAll(List<E> src, List<E> other) {}
static <E> List2<E> getList2() {
return new List2<E>();
}
static class List<E> {
void addAll(List<? extends E> other) {}
}
static class List2<E> {
void addAll(List2<E> other) {}
}
}
回答by LPD
This code will work for you.
getGenericList()
should know what it is returning and that should be compatible with your list type.
这段代码对你有用。
getGenericList()
应该知道它返回什么并且应该与您的列表类型兼容。
You need not cast it to String or any other as suggested by others as it will restrict your getGenericList method intention by tying it to string type.
您不需要将其转换为 String 或其他人建议的任何其他内容,因为它会通过将其绑定到字符串类型来限制您的 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();
}
}
}