2013-07-05 19 views
5

Ho letto ovunque che quando si definisce un numero intero compreso tra -128 e 127 in Java, invece di creare un nuovo oggetto restituisce un oggetto già creato.Pool intero Java. Perché?

Non vedo nessun altro modo di farlo se non quello di consentire ai programmatori principianti di confrontare gli oggetti interi con == per vedere se sono lo stesso numero, ma penso che questo sia sbagliato perché sicuramente pensano di poter confrontare qualsiasi numero intero con == e insegna anche una cattiva pratica in qualsiasi linguaggio di programmazione: confrontare il contenuto di due oggetti "diversi" con ==.

C'è qualche altra ragione sul perché questo è fatto? O è solo una brutta decisione quando si progetta il linguaggio (secondo me) come il punto e virgola opzionale in JavaScript?

EDIT: Vedo qui che spiegano il comportamento: Why does the behavior of the Integer constant pool change at 127?

sto chiedendo il motivo per cui è progettata per avere questo comportamento, e non perché sta succedendo questo comportamento.

+3

Sembra un po 'inutile allocare nuovi oggetti e occupare memoria quando sono comunque immutabili e possono essere condivisi. –

+0

Forse l'ottimizzazione della memoria è una risposta, non ci pensare. –

+0

Risparmia memoria, è molto più veloce e riduce la pressione sul garbage collector. Riusare gli oggetti può essere molto più veloce e alcune opzioni aumentano la dimensione della cache Integer a 10.000 o 20.000 per questo motivo. –

risposta

10

Si chiama Flyweight pattern e viene utilizzato per ridurre al minimo l'utilizzo della memoria.

È molto probabile che questi numeri vengano utilizzati ripetutamente e tipi di autobox come Integer non sono modificabili (si noti che ciò viene fatto non solo per Integer). La loro memorizzazione nella cache lo rende così non ci sono molte istanze e riduce anche GC (Garbage Collection).

Il JLS copre questo in 5.1.7. Boxing Conversion specificamente dicendo:

Se il valore p essere inscatolato è vero, falso, un byte, o un char nel campo \ u0000 a \ u007F, o un int o numero breve compreso tra -128 e 127 (incluso), quindi lasciare r1 e r2 i risultati di due conversioni di boxing pari a p. È sempre il caso che r1 == r2.

Idealmente, il boxing di un dato valore primitivo p, darebbe sempre un riferimento identico. In pratica, questo potrebbe non essere fattibile utilizzando le tecniche di implementazione esistenti. Le regole di cui sopra sono un compromesso pragmatico. La clausola finale sopra richiede che determinati valori comuni siano sempre racchiusi in oggetti indistinguibili. L'implementazione può memorizzarli in cache, pigramente o impazientemente. Per altri valori, questa formulazione non ammette alcuna ipotesi sull'identità dei valori inseriti nella parte del programmatore. Ciò consentirebbe (ma non richiederà) la condivisione di alcuni o tutti questi riferimenti.

Ciò garantisce che, nei casi più comuni, il comportamento sarà quello desiderato, senza imporre una penalità di prestazioni eccessive, in particolare su dispositivi di piccole dimensioni. Ad esempio, meno implementazioni a memoria limitata potrebbero memorizzare nella cache tutti i valori char e short, nonché i valori int e long nell'intervallo da -32K a +32K.

+0

Questa non era la prima risposta, ma è una risposta più dettagliata. Non mi piace l'ottimizzazione del sofware java per me. Penso che l'ottimizzazione del software appartenga allo sviluppatore. Voglio dire, hanno cambiato il modo in cui gli oggetti dovrebbero funzionare solo per ottimizzare il software degli utenti. Se uno sviluppatore vuole ottimizzarlo, dovrebbe lavorarci creando il proprio pool Integer. Ma questa è la mia opinione: P –

+1

E ora ho letto della modifica della conversione di boxe e ha più senso. Java funziona con milioni di dispositivi con differenze hardware davvero grandi, quindi hanno dovuto pensare a ridurre l'utilizzo della memoria ad ogni costo. Buon lavoro Java: P –

+1

Direi che l'intero * punto * di un linguaggio di alto livello come Java sta nascondendo i dettagli cruenti da parte dell'utente finale quando possibile;) Ma questo in particolare ... eh, potrei andare in entrambi i modi. –

2

Penso che la creazione di qualsiasi oggetto richieda più tempo rispetto a prenderlo dalla tabella dei simboli. Inoltre, se non sbaglio, ogni oggetto nell'heap occupa 24 byte di spazio aggiuntivo per l'intestazione. Ora, se un programmatore scrive il suo programma, la maggior parte delle operazioni viene eseguita su piccoli int (in questo caso, piccoli interi). In questo modo è possibile risparmiare molto spazio e migliorare un po 'le prestazioni.

+0

Sono curioso .. Perché 24? Su quale JVM? – Joni

+0

Sì, ora ha più senso ... Non pensavo alla memoria, che vergogna lol: P Grazie. –

+0

Penso a molti di loro. Non so perché esattamente 24 per l'intestazione. Penso che ci debba essere una firma o qualcosa di simile. + se la memoria totale non è divisibile per 8, viene aggiunto anche il padding (nel caso Integer è un wrapper per int-24 (header) + 4 (int) + 4 (padding)) –