Quando utilizzare primitive vs class in Java?

45

Vedo che Java ha un valore booleano (classe) vs booleano (primitivo). Allo stesso modo, c'è un intero (classe) vs int (primitivo). Qual è la migliore pratica su quando utilizzare la versione primitiva rispetto alla classe? Dovrei fondamentalmente utilizzare sempre la versione di classe a meno che non abbia una ragione specifica (prestazioni?) Per non farlo? Qual è il modo più comune e accettato di usarli?

    
posta Casey Patton 07.07.2013 - 10:15
fonte

5 risposte

41

Nell'articolo 5, di Effective Java, Joshua Bloch dice

The lesson is clear: prefer primitives to boxed primitives, and watch out for unintentional autoboxing.

Un buon uso per le classi è quando li si utilizza come tipi generici (comprese le classi Collection, come elenchi e mappe) o quando si desidera trasformarli in un altro tipo senza casting implicito (ad esempio Integer class ha metodi doubleValue() o byteValue() .

Modifica: il motivo di Joshua Bloch è:

// Hideously slow program! Can you spot the object creation?
public static void main(String[] args) {
    Long sum = 0L;
    for (long i = 0; i < Integer.MAX_VALUE; i++) {
         sum += i;
    }
    System.out.println(sum);
}

This program gets the right answer, but it is much slower than it should be, due to a one-character typographical error. The variable sum is declared as a Long instead of a long, which means that the program constructs about 2^31 unnecessary Long instances (roughly one for each time the long i is added to the Long sum). Changing the declaration of sum from Long to long reduces the runtime from 43 seconds to 6.8 seconds on my machine.

    
risposta data 07.07.2013 - 10:47
fonte
27

La pratica standard è di andare con i primitivi, a meno che tu non abbia a che fare con i generici (assicurati di essere a conoscenza di autoboxing & unboxing !).

Ci sono una serie di buoni motivi per seguire la convenzione:

1. Evita errori semplici:

Ci sono alcuni casi sottili e non intuitivi che spesso catturano i principianti. Anche i codificatori esperti si sbagliano e fanno questi errori qualche volta (si spera che questo sia seguito da un errore quando eseguono il debug del codice e trovano l'errore!).

L'errore più comune è l'utilizzo di a == b anziché a.equals(b) . Le persone sono abituate a fare a == b con le primitive, quindi è facile farlo quando usi i wrapper di oggetti.

Integer a = new Integer(2);
Integer b = new Integer(2);
if (a == b) { // Should be a.equals(b)
    // This never gets executed.
}
Integer c = Integer.valueOf(2);
Integer d = Integer.valueOf(2);
if (c == d) { // Should be a.equals(b), but happens to work with these particular values!
    // This will get executed
}
Integer e = 1000;
Integer f = 1000;
if (e == f) { // Should be a.equals(b)
    // Whether this gets executed depends on which compiler you use!
}

2. Leggibilità:

Considera i seguenti due esempi. La maggior parte delle persone direbbe che il secondo è più leggibile.

Integer a = 2;
Integer b = 2;
if (!a.equals(b)) {
    // ...
}
int c = 2;
int d = 2;
if (c != d) {
    // ...
}

3. Performance:

Il fatto è che è più lento usare i wrapper Object per le primitive piuttosto che usare solo le primitive. Stai aggiungendo il costo di creazione di istanze di oggetti, chiamate di metodi, ecc. A cose che usi ovunque sul posto .

Knuth "... diciamo circa il 97% delle volte: l'ottimizzazione prematura è la radice di tutti i mali" la citazione non si applica proprio qui. Stava parlando di ottimizzazioni che rendono il codice (o il sistema) più complicato - se sei d'accordo con il punto 2, questa è un'ottimizzazione che rende il codice meno complicato!

4. È la convenzione:

Se fai scelte stilistiche diverse al 99% degli altri programmatori Java, ci sono 2 aspetti negativi:

  • Troverai il codice di altre persone più difficile da leggere. Il 99% degli esempi / tutorial / etc là fuori useranno le primitive. Ogni volta che ne leggi uno, avrai il sovraccarico cognitivo in più di pensare a come apparirebbe nello stile a cui sei abituato.
  • Altre persone troveranno il tuo codice più difficile da leggere. Ogni volta che fai domande su Stack Overflow, devi passare attraverso risposte / commenti che chiedono "perché non usi le primitive?". Se non mi credi, guarda le battaglie che le persone hanno su cose come il posizionamento delle parentesi, che non influisce nemmeno sul codice generato!

Normalmente vorrei elencare alcuni contro-punti, ma onestamente non riesco a pensare a nessuna buona ragione per non andare con la convenzione qui!

    
risposta data 08.07.2013 - 16:31
fonte
12

Di solito vado con i primitivi. Tuttavia, una particolarità dell'uso di classi come Integer e Boolean è la possibilità di assegnare null a quelle variabili. Ovviamente, questo significa che devi eseguire null per tutto il tempo, ma è ancora meglio ottenere una NullPointerException piuttosto che avere errori logici dovuti all'utilizzo di alcune int o boolean variabili che non sono state inizializzate correttamente.

Inoltre, introduce la possibilità di usare null per assegnare a quelle variabili un valore " sconosciuto " o " carattere jolly ". Questo può essere utile in alcune situazioni, ad esempio, in Logica ternaria . O potresti voler controllare se un certo oggetto corrisponde a qualche modello; in questo caso puoi utilizzare null per quelle variabili nel modello che possono avere qualsiasi valore nell'oggetto.

    
risposta data 07.07.2013 - 11:23
fonte
2

In parole semplici:

Usi i wrapper quando devi aggiungere oggetti alle collezioni.

Le raccolte non possono contenere le primitive.

    
risposta data 08.07.2013 - 16:17
fonte
0

Funzionalità di autoboxing di Java come indicato da m3th0dman. Pensa al livello più basso possibile e vedrai che l'autoboxing (in entrata o in uscita) di un valore primitivo implicherà cicli di clock spesi in alcune attività che non ti servono se stai lavorando con tipi di dati nativi attorno all'applicazione.

Come regola generale, dovresti provare a utilizzare i tipi di dati nativi quando possibile.

    
risposta data 08.07.2013 - 16:20
fonte

Leggi altre domande sui tag