¿Hay alguna preferencia o diferencia de comportamiento entre usar:
if(obj.getClass().isArray()) {}
y
if(obj instanceof Object[]) {}
?
¿Hay alguna preferencia o diferencia de comportamiento entre usar:
if(obj.getClass().isArray()) {}
y
if(obj instanceof Object[]) {}
?
Respuestas:
En la mayoría de los casos, debe usar el instanceof
operador para probar si un objeto es una matriz.
En general, prueba el tipo de un objeto antes de convertirlo a un tipo particular que se conoce en tiempo de compilación. Por ejemplo, quizás escribiste algún código que puede funcionar con a Integer[]
o an int[]
. Desea proteger sus yesos 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 ...
En el nivel de JVM, el instanceof
operador se traduce en un código de bytes "instancia de" específico , que está optimizado en la mayoría de las implementaciones de JVM.
En casos más raros, es posible que esté utilizando la reflexión para atravesar un gráfico de objetos de tipos desconocidos. En casos como este, el isArray()
método 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.
Hay dos casos especiales: referencias nulas y referencias a matrices primitivas.
Una referencia nula causará el instanceof
resultado false
, mientras que la isArray
lanza a NullPointerException
.
Aplicado a una matriz primitiva, los instanceof
rendimientos a false
menos que el tipo de componente en el operando de la derecha coincida exactamente con el tipo de componente. Por el contrario, isArray()
volverá true
para cualquier tipo de componente.
obj instanceof int[]
cede false
cuando asigna un int[]
a obj
, está equivocado.
obj instanceof Object[]
produce false
si Object obj = new int[7]
.
java.lang.Object
, por lo que tiene sentido. Pero instanceof
aún se puede usar para probar matrices primitivas.
isArray()
debe utilizar la llamada a las matrices . En el caso especial no muy general de tener solo matrices de objetos, instanceof
proporciona una alternativa de alto rendimiento.
Si obj
es de tipo int[]
say, entonces tendrá una matriz Class
pero no será una instancia de Object[]
. Entonces, ¿qué quieres hacer obj
? Si vas a lanzarlo, ve con instanceof
. Si vas a usar la reflexión, entonces úsala .getClass().isArray()
.
getClass().isArray()
es significativamente más lento en Sun Java 5 o 6 JRE que en IBM.
Tanto que el uso clazz.getName().charAt(0) == '['
es más rápido en Sun JVM.
Recientemente tuve un problema al actualizar una aplicación Groovy de JDK 5 a JDK 6. El uso isArray()
falló en JDK6:
MissingMethodException:
No signature of sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl.isArray() ...
Cambiando a instanceof Object[]
arreglado esto.
isArray
es un método de Class
, no Type
, así que por supuesto GenericArrayTypeImpl
no tiene ese método. Y getClass
nunca puede devolver un non- Class
Type
, por lo que usted (o Groovy ??) debe haber hecho algo mal para obtener esto, como asumir que cada uno Type
es un Class
.
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 JPA, entonces necesita usar la funcionalidad isArray ().
Hice un blog sobre esto a principios de diciembre. http://blog.adamsbros.org/2010/12/08/java-array-reflection/
Si alguna vez tiene la opción de elegir entre una solución reflectante y una no reflectante, nunca elija la reflectante (que involucra objetos de clase). No es que sea "incorrecto" ni nada, pero cualquier cosa que implique reflexión es generalmente menos obvia y menos clara.
No hay diferencia en el comportamiento que pueda encontrar entre los dos (aparte del obvio caso nulo). En cuanto a qué versión preferiría, iría 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 usar el primero para ser más explícito si los revisores de código siguen preguntando al respecto.