Java数组反射:isArray与instanceof


177

使用以下内容之间是否存在偏好或行为差异:

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

if(obj instanceof Object[]) {}

Answers:


203

在大多数情况下,应使用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任何组件类型。


7
是的,但是会有什么不同呢?在我看来,这听起来像是微优化。
迈克尔·迈尔斯

2
@Dims如果你声称obj instanceof int[]的产量false当你分配int[]obj,你就错了。
erickson

4
对不起,我的意思是obj instanceof Object[]收益率false,如果Object obj = new int[7]
Dims

3
正确,在Java中,原始数据类型不是对象,并且不扩展java.lang.Object,所以这很有意义。但是instanceof仍然可以用来测试原始数组。
erickson

4
-1:通常,由于基本数组isArray()应使用调用数组。在仅具有对象阵列的非常普遍的特殊情况下,instanceof提供了高性能的替代方案。
Sam Harwell

33

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


8

如果obj是类型int[],则将具有一个数组,Class但不是的实例Object[]。那你想做什么呢obj。如果要投射,请使用instanceof。如果要使用反射,请使用.getClass().isArray()



4

我最近遇到了一个问题,将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
kaqqao


2

如果您在反射解决方案和非反射解决方案之间进行选择,请不要选择反射解决方案(涉及Class对象)。并不是说它是“错误”之类的东西,而是涉及反射的东西通常不太明显也不清晰。


嗯,“ instanceof”也是一种反思(或者至少是自省),但是我明白你的意思。
David Citron

而且,它通常较慢。
疯狂物理学家,2015年

0

我可以在两者之间找到行为上的区别(除了明显的空情况)。至于首选哪个版本,我会选择第二个版本。这是在Java中执行此操作的标准方法。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.