在使用ar.toArray(new String[ar.size()])
Android Studio 3.2.1时警告有关预定大小的数组,并建议使用空数组:
有两种样式可以将集合转换为数组: 预定大小的数组(例如c.toArray(new String [c.size()]))或使用 空数组(如c.toArray(new String [0])。在旧版Java中 建议使用预大小的数组,因为反射调用是 创建适当大小的数组所必需的速度非常慢。然而 自从OpenJDK 6的最新更新以来,此调用引起了人们的注意, 空数组版本的性能相同,有时甚至 比预大小版本更好。还通过了预尺寸 数组对于并发或同步集合是危险的,因为 在size和toArray调用之间可能发生数据争夺 如果集合是,则在数组末尾产生额外的null 在手术过程中同时缩小。该检查允许 遵循统一的样式:使用空数组(即 建议在现代Java中使用)或使用预定大小的数组(可能是 在较旧的Java版本或非基于HotSpot的JVM中更快。
是Android还是Java?
使用预定大小的数组(在较早的Java版本中可能更快 或非基于HotSpot的JVM)。
因为我认为Android不是HotSpot,其虚拟机是Dalvik,而现在是ART
答案 0 :(得分:1)
好问题。
https://shipilev.net/blog/2016/arrays-wisdom-ancients/#_new_reflective_array
底线:
toArray(new T[0])
似乎更快,更安全且符合合同规定 更清洁,因此现在应该是默认选择。未来虚拟机 优化可能会弥补toArray(new T[size])
的性能差距, 使当前“被认为是最佳”用法与 实际上是最佳选择。toArray
API中的Further improvements 遵循与toArray(new T[0])
相同的逻辑-集合本身 应该创建适当的存储。
答案 1 :(得分:0)
我不是Java历史学家,但是...
HotSpot实质上是由Oracle维护和分发的特定类型JVM的商标。它的名称来自即时编译器,该编译器可以检测到频繁执行的代码的“热点”并即时对其进行优化。
Android运行时也具有这种JIT编译器行为,并且可以在安装时将Java字节码提前编译为本机代码。
这使我认为ART与HotSpot属于同一类别(就此检查而言),因此您应该使用此调用的“空数组”版本。
如有疑问,请测量!
确定的最好方法是编写一个测试程序,该程序执行两种方法的版本并测量哪种方法运行得更快。
来源:
答案 2 :(得分:0)
它读取since late updates of OpenJDK 6
,使用哪个运行时都无关紧要-因为在Dalvik上作为编译类运行的代码的语言级别可能是Java 6、7 8.只关系到项目使用哪种语言级别进行编译。例如:
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
设置JavaVersion.VERSION_1_6
甚至可能会禁用检查投诉...在这些过时的设备上修复性能问题可能不值得付出努力-某些/大多数甚至都不会受到影响,因为只有“早期更新”行为与后续行为有所不同。