Java array reflection: isArray vs. instanceof
Is there a preference or behavior difference between using:
if(obj.getClass().isArray()) {}
and
if(obj instanceof Object[]) {}
?
In most cases, you should use the instanceof
operator to test whether an object is an array.
Generally, you test an object's type before downcasting to a particular type which is known at compile time. For example, perhaps you wrote some code that can work with a Integer[]
or an int[]
. You'd want to guard your casts with 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 ...
At the JVM level, the instanceof
operator translates to a specific "instanceof" byte code, which is optimized in most JVM implementations.
In rarer cases, you might be using reflection to traverse an object graph of unknown types. In cases like this, the isArray()
method can be helpful because you don't know the component type at compile time; you might, for example, be implementing some sort of serialization mechanism and be able to pass each component of the array to the same serialization method, regardless of type.
There are two special cases: null references and references to primitive arrays.
A null reference will cause instanceof
to result false
, while the isArray
throws a NullPointerException
.
Applied to a primitive array, the instanceof
yields false
unless the component type on the right-hand operand exactly matches the component type. In contrast, isArray()
will return true
for any component type.
In the latter case, if obj is null you won't get a NullPointerException but a false.
If obj
is of type int[]
say, then that will have an array Class
but not be an instance of Object[]
. So what do you want to do with obj
. If you are going to cast it, go with instanceof
. If you are going to use reflection, then use .getClass().isArray()
.
getClass().isArray()
is significantly slower on Sun Java 5 or 6 JRE than on IBM.
So much that using clazz.getName().charAt(0) == '['
is faster on Sun JVM.