Java List.toArray(T[]) 的奇怪泛型行为
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1073786/
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
Odd generics behaviour of List.toArray(T[])
提问by waxwing
I came across something very basic but extremely bewildering today. I needed to convert a list to an array. The list contained String
instances. Perfect example of using List.toArray(T[])
, since I wanted a String[]
instance. It would not work, however, without explicitly casting the result to String[]
.
我今天遇到了一些非常基本但非常令人困惑的事情。我需要将列表转换为数组。该列表包含String
实例。使用 的完美示例List.toArray(T[])
,因为我想要一个String[]
实例。但是,如果不将结果显式转换为String[]
.
As a test scenario, I used the following code:
作为测试场景,我使用了以下代码:
import java.util.Arrays;
import java.util.List;
public class MainClass {
public static void main(String args[]) {
List l = Arrays.asList("a", "b", "c");
String stuff[] = l.toArray(new String[0]);
System.err.println(Arrays.asList(stuff));
}
}
which does not compile. It's nearly an exact copy of the example in the javadoc, yet the compiler says the following:
这不编译。它几乎是javadoc 中示例的精确副本,但编译器会说以下内容:
MainClass.java:7: incompatible types
found : java.lang.Object[]
required: java.lang.String[]
String stuff[] = l.toArray(new String[0]);
^
If I add a cast to String[]
it will compile AND run perfectly. But that is not what I expect when I looked at the signature of the toArray method:
如果我向String[]
它添加演员表,它将编译并完美运行。但是当我查看 toArray 方法的签名时,这不是我所期望的:
<T> T[] toArray(T[] a)
This tells me that I shouldn't have to cast. What is going on?
这告诉我我不应该强制转换。到底是怎么回事?
Edit:
编辑:
Curiously, if I change the list declaration to:
奇怪的是,如果我将列表声明更改为:
List<?> l = Arrays.asList("a", "b", "c");
it also works. Or List<Object>
. So it doesn't have to be a List<String>
as was suggested. I am beginning to think that using the raw List
type also changes how generic methods inside that class work.
它也有效。或者List<Object>
。所以它不必List<String>
像建议的那样。我开始认为使用原始List
类型也会改变该类中泛型方法的工作方式。
Second edit:
第二次编辑:
I think I get it now. What Tom Hawtin wrote in a comment below seems to be the best explanation. If you use a generic type in the raw way, all generics information from that instance will be erased by the compiler.
我想我现在明白了。Tom Hawtin 在下面的评论中所写的似乎是最好的解释。如果您以原始方式使用泛型类型,则该实例中的所有泛型信息都将被编译器擦除。
采纳答案by dfa
you forgot to specify the type parameter for your List:
您忘记为您的列表指定类型参数:
List<String> l = Arrays.asList("a", "b", "c");
in this case you can write safety:
在这种情况下,您可以编写安全性:
String[] a = l.toArray(new String[0]);
without any cast.
没有任何演员。
回答by Paul Adamson
List<String> l = Arrays.asList("a", "b", "c");
this will make it compile, you're using generics to say "this is a list of Strings" so the toArray method knows which type of array to return.
这将使其编译,您使用泛型表示“这是一个字符串列表”,因此 toArray 方法知道要返回哪种类型的数组。
回答by JRL
That's because your list contains objects, not strings. Had you declared your list as List<String>
, the compiler would be happy.
那是因为您的列表包含对象,而不是字符串。如果您将列表声明为List<String>
,编译器会很高兴。
回答by user85421
or do
或做
List<?> l = Arrays.asList("a", "b", "c");
still strange
还是很奇怪
回答by henrik
List
without a declared type will default to "List of Object" while List<?>
means "List of unknown". In the world of generic types it is a fact that "List of Object" is different from "List of String" but the compiler cannot say the same for "List of unknown". If you've declared it as unknown then, as far as the compiler can tell, that's OK.
List
没有声明类型将默认为“对象列表”,而List<?>
表示“未知列表”。在泛型类型的世界中,事实是“对象列表”与“字符串列表”不同,但编译器不能对“未知列表”说相同的内容。如果您已将其声明为未知,那么就编译器而言,这没问题。
The main point is that declaring something as the wildcard ? is different from declaring it as Object. Read more about wildcards here
重点是将某些内容声明为通配符 ? 与将其声明为 Object 不同。在此处阅读有关通配符的更多信息