views:

6249

answers:

6

Is there a preference or behavior difference between using:

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

and

if(obj instanceof Object[]) {}

?

+21  A: 

In the latter case, if obj is null you won't get a NullPointerException but a false.

Burkhard
A: 

There is no difference in behavior that I can find between the two (other than the obvious null-case). As for which version to prefer, I would go with the second. It is the standard way of doing this in Java.

If it confuses readers of your code (because String[] instanceof Object[] is true), you may want to use the first to be more explicit if code reviewers keep asking about it.

hazzen
+1  A: 

If you ever have a choice between a reflective solution and a non-reflective solution, never pick the reflective one (involving Class objects). It's not that it's "Wrong" or anything, but anything involving reflection is generally less obvious and less clear.

Bill K
Er, well, "instanceof" is a kind of reflection (or, at least, introspection) as well, but I get your point.
David Citron
+19  A: 

In general, use the instanceof operator to test whether an object is an array.

At the JVM level, the instanceof operator translates to a specific "instanceof" byte code, which is highly optimized in most JVM implementations.

The reflective approach (getClass().isArray()) is compiled to two separate "invokevirtual" instructions. The more generic optimizations applied by the JVM to these may not be as fast as the hand-tuned optimizations inherent in the "instanceof" instruction.

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 results false, but the isArray returns true.

erickson
Yeah, but how much difference is it going to make? That sounds like a micro-optimization to me.
Michael Myers
It depends on the application, but I'd be surprised to find the difference large enough to be worth going out of your way for. But, since it's the conventional approach, you should have some special reason (like support for primitive arrays) to justify using the awkward, sub-optimal reflection.
erickson
+1  A: 

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().

Tom Hawtin - tackline
A: 

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.

Sebastien Tardif
Do you have any statistics, a case study, or other evidence that you can link to?
David Citron