Domanda

In realtà qui è un argomento simile con scarso valore pratico. Per quanto ho capito, le primitive funzionano meglio e dovrebbero essere utilizzate ovunque, tranne nei casi in cui sono necessarie funzionalità relative agli oggetti (ad es. Controllo null ). Giusto?

È stato utile?

Soluzione

Non dimenticare che, dal momento che la creazione di un nuovo wrapper per ogni occorrenza di boxe è piuttosto costosa, soprattutto considerando che di solito viene utilizzata in un singolo ambito di un metodo, Autoboxing utilizza un pool di wrapper comuni.

Questa è in effetti un'implementazione di modello di progettazione del peso mosca . Quando si verifica un inscatolamento per un valore noto, invece di creare una nuova istanza del wrapper, un'istanza pre-creata viene recuperata da un pool e restituita.

Una conseguenza è: non è ancora consigliabile utilizzare l'autoboxing per i calcoli scientifici . Ad esempio, il codice d = a * b + c utilizza le classi Integer per a, b, c e d e il codice generato è d.valueOf (a.intValue () * b.intValue () + c.intValue ( )). Tutte queste invocazioni di metodi hanno il loro overhead, quindi di solito si consiglia di utilizzare l'autoboxing quando necessario per archiviare le primitive nelle raccolte .

E anche in questo caso, se disponi di una vasta collezione di Integer wrapping int, l'overhead può implicare tempi di esecuzione più lunghi, fino a 20 volte più lunghi , come riportato in questo articolo .


Jb aggiunge questo importante commento:

  

Anche Wrapper.valueOf (primitivo) usa un pool di wrapper. Quindi preferisci Integer.valueOf (5) al nuovo Integer (5)

Altri suggerimenti

Le primitive sono più veloci quando vengono utilizzate , poiché gli oggetti devono essere decompressi prima dell'uso; pertanto è necessario un ulteriore passaggio da eseguire per la VM. Ad esempio, per eseguire l'aritmetica su un numero intero, è necessario prima convertirlo in un int prima di poter eseguire l'aritmetica.

In molte applicazioni aziendali questo probabilmente importa raramente. Ma se stavi scrivendo qualcosa di molto pesante come un processore di trasformazione grafica, è molto più probabile che ti interessi.

sì, le primitive sono più veloci degli oggetti. Da java 5 puoi anche mescolare primitivi e oggetti senza convertirli manualmente in un altro. Il meccanismo di autoboxing si occupa proprio di questo.

ciò significa che se si inserisce una primitiva in una raccolta, il compilatore non si lamenterà e convertirà implicitamente la primitiva in un oggetto.

Se hai bisogno di conservare le primitive nelle raccolte potresti usare commons-primitives .

Preferisco usare le primitive per i wrapper, solo i luoghi che devono assolutamente avere i wrapper sono le classi di entità. I database supportano null, quindi anche le entità dovrebbero.

Una volta ho lavorato a un progetto che utilizzava primitive (e homebrew ORM) nell'accesso al database:

 class Foo{
    int xxx = -1;
 ...
 }

E poi hai avuto:

 void persist(Foo foo){
     ...
     statement.setInt(15,foo.getXXX()==-1?null:foo.getXXX());
     ...
}

Dio era malvagio.

Direi che dovresti preoccuparti di usare le primitive sui wrapper solo quando esegui il profilo della tua applicazione e vedi che l'autoboxing è un problema di prestazioni o di memoria. Nella mia esperienza, la memoria diventa un problema prima dei cicli della CPU quando si parla di primitivi rispetto a oggetti avvolgenti.

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