Java数组reflection:isArray与instanceof

使用以下方法之间是否存在偏好或行为差异?

if(obj.getClass().isArray()) {} 

 if(obj instanceof Object[]) {} 

通常,使用instanceof运算符来testing一个对象是否是一个数组。

在JVM级别, instanceof运算符转换为特定的“instanceof”字节码,在大多数JVM实现中高度优化。

reflection方法( getClass().isArray() )被编译为两个单独的“invokevirtual”指令。 JVM应用于这些的更一般的优化可能不如“instanceof”指令中固有的手动优化那么快。

有两种特殊情况:空引用和对原始数组的引用。

null引用将导致instanceof导致false ,而isArray引发NullPointerException

应用于原始数组, instanceof产生false除非右边的操作数与组件types完全匹配。 相反,对于任何组件types, isArray()将返回true

在后一种情况下,如果obj为null,则不会得到NullPointerException,而是返回false。

如果obj的types是int[] ,那么它将有一个数组Class但不是Object[]一个实例。 那么你想用obj做什么? 如果你要投它,去instanceof 。 如果您要使用reflection,请使用.getClass().isArray()

getClass().isArray()在Sun Java 5或6 JRE上比在IBM上慢得多。

在Sun JVM上使用clazz.getName().charAt(0) == '['更快。

我最近遇到了将Groovy应用程序从JDK 5升级到JDK 6的问题。在JDK6中使用isArray()失败:

 MissingMethodException: No signature of sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl.isArray() ... 

更改为instanceof Object[]解决了这个问题。

Java数组reflection适用于您没有可用于执行“instanceof”的Class实例的情况。 例如,如果您正在编写某种注入框架,将值注入类的新实例(如JPA),则需要使用isArray()function。

我在十二月份的时候就博客提到了这个。 http://blog.adamsbros.org/2010/12/08/java-array-reflection/

如果您有reflection解决scheme和非reflection解决scheme之间的select,请不要selectreflection解决scheme(涉及Class对象)。 这并不是说它是“错”或什么的,但是涉及reflection的东西通常不那么明显,也不太清楚。

两者之间我可以find的行为没有区别(除了明显的空白情况)。 至于哪个版本更喜欢,我会与第二个去。 这是在Java中这样做的标准方式。

如果它使你的代码的读者感到困惑(因为String[] instanceof Object[]是真的),如果代码审阅者不断询问它,你可能希望使用第一个。