Answers:
在大多数情况下,应使用instanceof
运算符测试对象是否为数组。
通常,在向下转换为编译时已知的特定类型之前,需要测试对象的类型。例如,也许您编写了一些可以使用Integer[]
或的代码int[]
。您想使用以下方法保护自己的演员instanceof
:
if (obj instanceof Integer[]) {
Integer[] array = (Integer[]) obj;
/* Use the boxed array */
} else if (obj instanceof int[]) {
int[] array = (int[]) obj;
/* Use the primitive array */
} else ...
在JVM级别,instanceof
操作员将转换为特定的“ instanceof”字节代码,该代码在大多数JVM实现中都得到了优化。
在极少数情况下,您可能会使用反射遍历未知类型的对象图。在这种情况下,该isArray()
方法可能会有所帮助,因为您在编译时不知道组件类型。例如,您可能正在实现某种序列化机制,并且能够将数组的每个组件传递给相同的序列化方法,而不论其类型如何。
有两种特殊情况:空引用和对原始数组的引用。
空引用将导致instanceof
结果false
,而isArray
引发NullPointerException
。
施加到一个原始阵列,所述instanceof
产量false
除非在右边的操作数完全相同的组件类型的组件类型相匹配。相反,isArray()
将返回true
任何组件类型。
obj instanceof int[]
的产量false
当你分配int[]
到obj
,你就错了。
obj instanceof Object[]
收益率false
,如果Object obj = new int[7]
。
java.lang.Object
,所以这很有意义。但是instanceof
仍然可以用来测试原始数组。
isArray()
应使用调用的数组。在仅具有对象阵列的非常普遍的特殊情况下,instanceof
提供了高性能的替代方案。
getClass().isArray()
在Sun Java 5或6 JRE上比在IBM上慢得多。
clazz.getName().charAt(0) == '['
在Sun JVM上使用速度更快。
我最近遇到了一个问题,将Groovy应用程序从JDK 5升级到isArray()
JDK6 。在JDK6中使用失败:
MissingMethodException:
No signature of sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl.isArray() ...
更改以instanceof Object[]
解决此问题。
isArray
是的方法Class
,不是Type
,因此当然GenericArrayTypeImpl
没有该方法。并且getClass
永远无法返回非值Class
Type
,因此您(或Groovy ??)必须做错了什么才能获得此值,例如假设every Type
是a Class
。
Java数组反射用于以下情况:您没有可用于执行“ instanceof”的Class实例。例如,如果您正在编写某种注入框架,该注入框架将值注入到类的新实例中(例如JPA),则需要使用isArray()功能。
我在12月初发布了有关此内容的博客。 http://blog.adamsbros.org/2010/12/08/java-array-reflection/
如果您在反射解决方案和非反射解决方案之间进行选择,请不要选择反射解决方案(涉及Class对象)。并不是说它是“错误”之类的东西,而是涉及反射的东西通常不太明显也不清晰。