Existe uma diferença de preferência ou comportamento entre usar:
if(obj.getClass().isArray()) {}
e
if(obj instanceof Object[]) {}
?
Existe uma diferença de preferência ou comportamento entre usar:
if(obj.getClass().isArray()) {}
e
if(obj instanceof Object[]) {}
?
Respostas:
Na maioria dos casos, você deve usar o instanceof
operador para testar se um objeto é uma matriz.
Geralmente, você testa o tipo de um objeto antes de fazer o downcast para um tipo específico conhecido em tempo de compilação. Por exemplo, talvez você tenha escrito algum código que possa funcionar com a Integer[]
ou an int[]
. Você deseja proteger seus elencos com 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 ...
No nível da JVM, o instanceof
operador converte em um código de byte "instanceof" específico , que é otimizado na maioria das implementações da JVM.
Em casos mais raros, você pode estar usando a reflexão para percorrer um gráfico de objeto de tipos desconhecidos. Em casos como esse, o isArray()
método pode ser útil porque você não conhece o tipo de componente em tempo de compilação; você pode, por exemplo, implementar algum tipo de mecanismo de serialização e ser capaz de passar cada componente da matriz para o mesmo método de serialização, independentemente do tipo.
Existem dois casos especiais: referências nulas e referências a matrizes primitivas.
Uma referência nula causará o instanceof
resultado false
, enquanto os isArray
arremessos a NullPointerException
.
Aplicado a uma matriz primitiva, o instanceof
rendimento é feito false
, a menos que o tipo de componente no operando à direita corresponda exatamente ao tipo de componente. Por outro lado, isArray()
retornará true
para qualquer tipo de componente.
obj instanceof int[]
produz false
quando atribui um int[]
a obj
, está enganado.
obj instanceof Object[]
produz false
se Object obj = new int[7]
.
java.lang.Object
, o que faz sentido. Mas instanceof
ainda pode ser usado para testar matrizes primitivas.
isArray()
deve ser usada. No caso especial não geral de ter apenas matrizes de objetos, instanceof
fornece uma alternativa de alto desempenho.
Se obj
for do tipo int[]
say, isso terá uma matriz, Class
mas não será uma instância de Object[]
. Então, o que você quer fazer obj
? Se você vai lançá-lo, vá com instanceof
. Se você vai usar reflexão, use .getClass().isArray()
.
getClass().isArray()
é significativamente mais lento no Sun Java 5 ou 6 JRE do que na IBM.
Tanto que o uso clazz.getName().charAt(0) == '['
é mais rápido no Sun JVM.
Recentemente, deparei-me com um problema ao atualizar um aplicativo Groovy do JDK 5 para o JDK 6. O uso isArray()
falhou no JDK6:
MissingMethodException:
No signature of sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl.isArray() ...
Mudando para instanceof Object[]
corrigir isso.
isArray
é um método de Class
, não Type
, então é claro GenericArrayTypeImpl
que não tem esse método. E getClass
nunca pode retornar um não- Class
Type
, então você (ou Groovy ??) deve ter feito algo errado para obter isso, como assumir que cada Type
um é a Class
.
A reflexão da matriz Java é para casos em que você não possui uma instância da Classe disponível para executar "instanceof". Por exemplo, se você estiver escrevendo algum tipo de estrutura de injeção, que injeta valores em uma nova instância de uma classe, como a JPA, então você precisará usar a funcionalidade isArray ().
Eu escrevi sobre isso no início de dezembro. http://blog.adamsbros.org/2010/12/08/java-array-reflection/
Se você já tiver uma escolha entre uma solução reflexiva e uma não reflexiva, nunca escolha a reflexiva (envolvendo objetos de classe). Não é que seja "Errado" ou algo assim, mas qualquer coisa que envolva reflexão é geralmente menos óbvia e menos clara.
Não há diferença de comportamento que eu possa encontrar entre os dois (exceto o caso nulo óbvio). Quanto a qual versão preferir, eu iria com a segunda. É a maneira padrão de fazer isso em Java.
Se isso confunde os leitores do seu código (porque String[] instanceof Object[]
é verdade), convém usar o primeiro para ser mais explícito se os revisores de código continuarem perguntando sobre ele.