Domanda

Di solito il compilatore genera codice per eseguire boxe e unboxing. Ma cosa fa il compilatore, se non sono necessari i valori in scatola? È il (Oracle standard) compilatore abbastanza intelligente per ottimizzare via?

Date un'occhiata a questo metodo:

public static void requireInRange(int index, Object[] array) {
    if(index < 0 || index >= array.length)
        throw new IndexOutOfBoundsException();
}

L'informazione rilevante solo il array.length, quindi sarebbe inutile scatola ogni valore di un array per esempio. Come in questo codice:

int[] anArray = {3, 4, 2};
requireInRange(3, anArray);

Sarà il compilatore in realtà Inserisci Codice per la boxe ogni valore della matrice?

È stato utile?

Soluzione

Non c'è autoboxing nel codice. In effetti, data:

public static void requireInRange(int index, Object[] array) {
   ...
}

int[] anArray = {3, 4, 2};
requireInRange(3, anArray); // DOES NOT COMPILE!!!

Mentre un int può essere autoboxed a un Integer, un int[] non get autoboxed a Integer[] da Java. È possibile scrivere funzioni di libreria per fare questo, ma la lingua non sarà facilitare questa conversione.

Questo è infatti la fonte di molti confusione riguardo esempio Arrays.asList(anIntArray) essere "rotto", perché invece di restituire un List<Integer>, ciò che viene restituito è in effetti un List<int[]> un elemento.


Ma per quanto riguarda le prestazioni ???

Una citazione da Java Language Guide / Autoboxing :

  

Non è opportuno utilizzare autoboxing e unboxing per il calcolo scientifico, o altro codice numerico prestazioni sensibili. Un Integer non è un sostituto per un int; autoboxing e sfocatura unboxing la distinzione tra tipi primitivi e tipi di riferimento, ma non eliminarlo.

In breve, quando autoboxing accade, performance prende sicuramente un po 'di un colpo. Certe cose contribuire ad alleviare questo, ad esempio, il meccanismo di cache incorporato in questi tipi. Questo è il motivo per cui si ottiene la seguente:

    System.out.println(
        ((Integer) 0) == ((Integer) 0)
    );
    // true

    System.out.println(
        ((Integer) 10000) == ((Integer) 10000)
    );
    // false (implementation-specific)

Quello che è successo è che quando 0 è automaticamente in scatola, senza nuovo istanza Integer è effettivamente creato: valori in certo intervallo è Copia cache per scopi autoboxing, per aiutare le prestazioni. 10000 nella maggior parte implementazione probabilmente cade fuori di questo intervallo, ma alcune implementazioni JVM fare permettono di specificare l'intervallo di cache, se necessario.


Ma voglio solo per ottenere la lunghezza dell'array !!!

Ci sono molti modi per facilitare il vostro requireInRange per lavorare con qualsiasi tipo di array. Purtroppo lavorare con serie di Java di primitive spesso significa un sacco di ripetizione. Questo significa fornire sovraccarichi per int[], boolean[], byte[], Object[], ecc separatamente.

Una soluzione più concisa è quello di utilizzare la riflessione, ma questo ha i suoi vantaggi e svantaggi. In generale, la riflessione non dovrebbe essere la soluzione preferita per la maggior parte degli scenari.

Detto questo, java.lang.reflect.Array ha un int getLength(Object array) static metodo che può restituire la lunghezza del array QUALSIASI. Non è typesafe (come la maggior parte meccanismo di riflessione sono); passando un non-matrice compilazioni, ma getta IllegalArgumentException in fase di esecuzione.

Domande correlate

Altri suggerimenti

  

Sarà codice del compilatore in realtà inserto   per la boxe ogni valore della matrice?

Il compilatore rifiuterà il codice perché un int[] non può essere passato in un metodo che accetta un parametro Object[].

Autoboxing avviene solo per i singoli valori primitivi, mai per intero array.

In caso di dubbio, si può assumere il compilatore non ottimizzare il codice. In generale si fa una traduzione letterale del codice.

Inoltre, in caso di dubbio youc un assumere la JVM fa un ottimo lavoro di ottimizzazione del codice in fase di esecuzione. Non vorrei pensare che fa alcuna differenza se non si ha una buona ragione (come profiler) a sospettare è un problema.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top