2008-10-20 16 views

Respuesta

188

En la mayoría de los casos, debe usar el operador instanceof para probar si un objeto es una matriz.

Generalmente, se prueba el tipo de un objeto antes de la bajada a un tipo particular que se conoce en tiempo de compilación. Por ejemplo, quizás haya escrito algún código que pueda funcionar con Integer[] o int[]. Lo que quiere proteger sus moldes con 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 ... 

A nivel JVM, el operador instanceof traduce a un código de bytes "instanceof" específica, que está optimizado en la mayoría de las implementaciones de JVM.

En casos más raros, puede estar utilizando la reflexión para recorrer un gráfico de objetos de tipos desconocidos. En casos como este, el método isArray() puede ser útil porque no conoce el tipo de componente en tiempo de compilación; podría, por ejemplo, implementar algún tipo de mecanismo de serialización y poder pasar cada componente de la matriz al mismo método de serialización, independientemente del tipo.

Existen dos casos especiales: referencias nulas y referencias a matrices primitivas.

Una referencia nula causará instanceof a false, mientras que isArray arroja un NullPointerException.

Aplicado a una matriz primitiva, el instanceof produce false a menos que el tipo de componente en el operando de la derecha coincida exactamente con el tipo de componente. Por el contrario, isArray() devolverá true para cualquier tipo de componente.

+7

Sí, pero ¿cuánta diferencia va a hacer? Eso me suena a una micro-optimización. –

+0

Depende de la aplicación, pero me sorprendería encontrar la diferencia lo suficientemente grande como para merecer la pena. Pero, dado que es el enfoque convencional, debe tener alguna razón especial (como soporte para matrices primitivas) para justificar el uso de la reflexión incómoda y subóptima. – erickson

+6

'instanceof' no funcionará con matrices de tipos integrales. – Dims

31

En este último caso, si obj es nulo, no obtendrá una NullPointerException sino una falsa.

0

No hay diferencia en el comportamiento que puedo encontrar entre los dos (que no sea el caso nulo obvio). En cuanto a la versión que prefiera, me gustaría ir con la segunda. Es la forma estándar de hacer esto en Java.

Si confunde a los lectores de su código (porque String[] instanceof Object[] es cierto), es posible que desee utilizar el primero para ser más explícito si los revisores de códigos siguen preguntando al respecto.

2

Si alguna vez tiene la opción entre una solución reflectante y una no reflectante, nunca elija la reflectante (que involucra objetos Class). No es que sea "Incorrecto" ni nada, pero cualquier cosa que implique reflexión es generalmente menos obvia y menos clara.

+0

Er, bueno, "instanceof" es un tipo de reflejo (o, al menos, introspección) también, pero entiendo tu punto. –

+0

Además, generalmente es más lento. –

8

Si obj es de tipo int[] decir, después de que se tiene una matriz Class pero no ser una instancia de Object[]. Entonces, ¿qué quieres hacer con obj. Si vas a lanzarlo, ve con instanceof. Si va a utilizar la reflexión, utilice .getClass().isArray().

4

getClass().isArray() es significativamente más lento en Sun Java 5 o 6 JRE que en IBM.

Tanto que usar clazz.getName().charAt(0) == '[' es más rápido en Sun JVM.

+10

¿Tiene alguna estadística, estudio de caso u otra evidencia a la que pueda vincular? –

3

La reflexión de matriz de Java es para casos en los que no tiene una instancia de la clase disponible para hacer "instanceof". Por ejemplo, si está escribiendo algún tipo de marco de inyección, que inyecta valores en una nueva instancia de una clase, como lo hace JPA, entonces necesita usar la funcionalidad isArray().

He escrito sobre esto a principios de diciembre. http://blog.adamsbros.org/2010/12/08/java-array-reflection/

4

Hace poco me encontré con un problema de actualizar una aplicación maravillosa de JDK 5 a JDK 6. El uso de isArray() fracasaron en JDK6:

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

El cambio a este instanceof Object[] fijo.

+0

Esto no tiene sentido. 'isArray' es un método de' Class', no 'Type', por lo que' GenericArrayTypeImpl' no tiene ese método. Y 'getClass' nunca puede devolver un' Tipo' no 'Clase', por lo que (o Groovy ??) debe haber hecho algo incorrecto para obtener esto, como suponer que cada 'Tipo' es una 'Clase'. – kaqqao