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[]
是真的),如果代码审阅者不断询问它,你可能希望使用第一个。