C'è una preferenza o una differenza di comportamento tra l'utilizzo di:
if(obj.getClass().isArray()) {}
e
if(obj instanceof Object[]) {}
?
C'è una preferenza o una differenza di comportamento tra l'utilizzo di:
if(obj.getClass().isArray()) {}
e
if(obj instanceof Object[]) {}
?
Risposte:
Nella maggior parte dei casi, è necessario utilizzare l' instanceof
operatore per verificare se un oggetto è un array.
In genere, si verifica il tipo di un oggetto prima di eseguire il downcasting a un tipo particolare noto al momento della compilazione. Ad esempio, forse hai scritto del codice che può funzionare con un Integer[]
o un int[]
. Vorresti proteggere i tuoi cast 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 livello di JVM, il instanceof
operatore si traduce in uno specifico codice byte "instanceof" , che è ottimizzato nella maggior parte delle implementazioni JVM.
In casi più rari, potresti usare la riflessione per attraversare un grafico a oggetti di tipo sconosciuto. In casi come questo, il isArray()
metodo può essere utile perché non si conosce il tipo di componente al momento della compilazione; ad esempio, è possibile implementare una sorta di meccanismo di serializzazione ed essere in grado di passare ciascun componente dell'array allo stesso metodo di serializzazione, indipendentemente dal tipo.
Esistono due casi speciali: riferimenti null e riferimenti ad array primitivi.
Un riferimento nullo causerà instanceof
ai risultati false
, mentre la isArray
tiri unNullPointerException
.
Applicati a una matrice primitiva, i instanceof
rendimenti a false
meno che il tipo di componente sull'operando di destra non corrisponda esattamente al tipo di componente. Al contrario, isArray()
verrà restituito true
per qualsiasi tipo di componente.
obj instanceof int[]
rendimenti false
quando assegni un int[]
a obj
, ti sbagli.
obj instanceof Object[]
cede false
se Object obj = new int[7]
.
java.lang.Object
, quindi ha senso. Ma instanceof
può ancora essere usato per testare array primitivi.
isArray()
necessario utilizzare la chiamata . Nel caso molto generale non speciale di avere solo matrici di oggetti, instanceof
offre un'alternativa ad alte prestazioni.
Se obj
è di tipo int[]
dire, allora avrà un array Class
ma non sarà un'istanza di Object[]
. Quindi con cosa vuoi fare obj
. Se hai intenzione di lanciarlo, vai con instanceof
. Se hai intenzione di usare la riflessione, allora usa .getClass().isArray()
.
getClass().isArray()
è significativamente più lento su Sun Java 5 o 6 JRE che su IBM.
Tanto che l'utilizzo clazz.getName().charAt(0) == '['
è più veloce su Sun JVM.
Di recente ho isArray()
riscontrato un problema durante l'aggiornamento di un'applicazione Groovy da JDK 5 a JDK 6. Utilizzo non riuscito in JDK6:
MissingMethodException:
No signature of sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl.isArray() ...
Cambiando per instanceof Object[]
risolvere questo problema.
isArray
è un metodo di Class
no Type
, quindi ovviamente GenericArrayTypeImpl
non ha quel metodo. E getClass
non puoi mai restituire un non- Class
Type
, quindi tu (o Groovy ??) devi aver fatto qualcosa di sbagliato per ottenerlo, come supporre che ogni Type
sia un Class
.
La riflessione dell'array Java è per i casi in cui non si dispone di un'istanza della classe disponibile per eseguire "instanceof". Ad esempio, se stai scrivendo una sorta di framework di iniezione, che inietta valori in una nuova istanza di una classe, come fa JPA, allora devi usare la funzionalità isArray ().
Ho scritto questo blog all'inizio di dicembre. http://blog.adamsbros.org/2010/12/08/java-array-reflection/
Se hai mai una scelta tra una soluzione riflettente e una soluzione non riflettente, non scegliere mai quella riflettente (che coinvolge oggetti di classe). Non è che sia "sbagliato" o altro, ma tutto ciò che comporta la riflessione è generalmente meno ovvio e meno chiaro.
Non c'è alcuna differenza nel comportamento che posso trovare tra i due (a parte l'evidente caso nullo). Per quanto riguarda quale versione preferirei, andrei con il secondo. È il modo standard di farlo in Java.
Se confonde i lettori del tuo codice (perché String[] instanceof Object[]
è vero), potresti voler usare il primo per essere più esplicito se i revisori del codice continuano a chiederlo.