使用之间是否存在偏好或行为差异:
if(obj.getClass().isArray()) {}
和
if(obj instanceof Object[]) {}
答案 0 :(得分:198)
在大多数情况下,您应该使用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
。
答案 1 :(得分:32)
在后一种情况下,如果obj为null,则不会得到NullPointerException而是false。
答案 2 :(得分:8)
如果obj
的类型为int[]
,那么它将有一个数组Class
,但不是Object[]
的实例。那么你想用obj
做什么?如果您要进行投射,请使用instanceof
。如果您要使用反射,请使用.getClass().isArray()
。
答案 3 :(得分:5)
我最近遇到了将Groovy应用程序从JDK 5升级到JDK 6的问题。在JDK6中使用isArray()
失败:
MissingMethodException:
No signature of sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl.isArray() ...
更改为instanceof Object[]
已解决此问题。
答案 4 :(得分:4)
getClass().isArray()
明显慢于IBM。
在Sun JVM上使用clazz.getName().charAt(0) == '['
的速度更快。
答案 5 :(得分:3)
Java数组反射适用于您没有可用于执行“instanceof”的类实例的情况。例如,如果您正在编写某种注入框架,它将值注入到类的新实例中,例如JPA,那么您需要使用isArray()函数。
我在12月早些时候在博客上写过这篇文章。 http://blog.adamsbros.org/2010/12/08/java-array-reflection/
答案 6 :(得分:2)
如果您可以选择反射解决方案和非反射解决方案,请不要选择反射解决方案(涉及Class对象)。这不是“错误”或任何事情,但任何涉及反思的事情通常都不那么明显,也不那么清晰。
答案 7 :(得分:0)
我可以在两者之间找到的行为没有区别(明显的空案例除外)。至于喜欢哪个版本,我会选择第二个版本。这是在Java中执行此操作的标准方法。
如果它使您的代码的读者感到困惑(因为String[] instanceof Object[]
为真),如果代码审核者不断询问,您可能希望使用第一个更明确。