toArray(new String[0])中的new String[0]有什么用途?

29

为什么在toArray中需要参数new String[0]

saved = getSharedPreferences("searches", MODE_PRIVATE);
String[] mystring = saved.getAll().keySet().toArray(new String[0]);
3个回答

39
这样你就可以得到一个String[]。没有参数的那个会返回一个Object[]
你可以看到这个方法有两个版本: 通过传递String[]数组,您正在使用通用版本。
更好的方法是使用Set的大小来初始化String[]数组,而不是使用大小为0的数组,这样就不需要在方法中创建新数组了。
Set<String> set = saved.getAll().keySet();
String[] mystring = set.toArray(new String[set.size()]);

4
我个人觉得这个要求有点奇怪,通过传递Class.class更符合我的逻辑。 - StormeHawke
1
@StormeHawke,这会涉及到反射,比创建一个数组的开销要大。 - nanofarad
4
最好将数组初始化为正确的大小,这样它就可以被填充。否则,将创建一个新数组。 - Sam Barnum
2
@SamBarnum 有人知道为什么Intellij IDEA(2018.1,2019.2)提供一个数组吗? - Dan Brandt
7
我认为在Java 8中使用空数组实际上更有效率。https://dev59.com/j3VC5IYBdhLWcg3w0EsD#29444594 - Sam Barnum
显示剩余3条评论

7
补充一下已被接受的答案,一些IDE(这里是IntelliJ)会对活动检查时使用new String[c.size()]与使用new String[0]作为toArray 方法的参数进行有用的注释和解释:

将集合转换为数组有两种方式:使用预先调整大小的数组(例如c.toArray(new String[c.size()]))或使用空数组(例如c.toArray(new String[0]))。在早期的Java版本中,推荐使用预先调整大小的数组,因为创建合适大小的数组所需的反射调用非常缓慢。然而,自OpenJDK 6的最新更新以来,该调用已经内联化,使得空数组版本的性能相同,有时甚至比预先调整大小的版本更好。同时,向预先调整大小的数组传递参数对于并发或同步集合来说是危险的,因为在大小和toArray调用之间可能会出现数据竞争,如果在操作期间同时缩小了集合,则可能会在数组末尾产生额外的null值。此检查允许遵循统一的样式:使用空数组(在现代Java中推荐)或使用预先调整大小的数组(在旧的Java版本或基于非热点的JVM中可能更快)。

希望这能够进一步理解为什么要以某种方式做事情。

NetBeans 18刚刚警告了toArray(new Predicate[]{})并建议使用toArray(Predicate[]::New)代替。很有意思想知道为什么。 - Mark Wood

5

这是为了提供返回类型并防止编译时出现歧义。

该方法的签名为:<T> T[] toArray(T[] a)

而空参数的方法签名为:Object[] toArray()


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接