riferimento - tipi primitivi java definizione




Quando utilizzare i tipi primitivi e di riferimento in Java (7)

In tal caso dovresti usare tipi primitivi ( int ) o tipi di riferimento ( Integer )?

Questa question suscitato la mia curiosità.


In tal caso dovresti usare tipi primitivi ( int ) o tipi di riferimento ( Integer )?

Come regola generale, userò una primitiva (come int ) a meno che non debba usare una classe che avvolge una primitiva.

Uno dei casi in cui è necessario utilizzare una classe wrapper come Integer è nel caso di utilizzo di generics , in quanto Java non supporta l'utilizzo di tipi primitivi come parametri di tipo:

List<int> intList = new ArrayList<int>();               // Not allowed.
List<Integer> integerList = new ArrayList<Integer>();   // Allowed.

E, in molti casi, trarrò vantaggio dall'autoboxing e dall'unboxing , quindi non devo eseguire esplicitamente conversioni dalle primitive alla sua classe wrapper e viceversa:

// Autoboxing will turn "1", "2", "3" into Integers from ints.
List<Integer> numbers = Arrays.asList(1, 2, 3); 

int sum = 0;

// Integers from the "numbers" List is unboxed into ints.
for (int number : numbers) {
  sum += number;
}

Inoltre, come nota aggiuntiva, quando si converte dalle primitive agli oggetti della classe wrapper e non sono necessarie istanze di oggetti univoche, utilizzare il metodo valueOf fornito dal metodo wrapper, poiché esegue la memorizzazione nella cache e restituisce la stessa istanza per un determinato valore, riducendo il numero di oggetti che vengono creati:

Integer i1 = Integer.valueOf(1);   // Prefer this.
Integer i2 = new Integer(1);       // Avoid if not necessary.

Per ulteriori informazioni sui metodi valueOf , la specifica API per il metodo Integer.valueOf può fungere da riferimento per il modo in cui tali metodi si comportano nelle classi wrapper per le primitive.


La mia regola generale è: usare le primitive in scatola solo quando è necessario ottenere il codice da compilare. Le uniche posizioni nel codice in cui devono essere visualizzati i nomi delle classi di wrapper primitive sono i parametri di tipo generico e le chiamate al metodo statico:

List<Integer> intList = new ArrayList<Integer>();

int n = Integer.parseInt("123");

Questo è il consiglio che darei ai nuovi programmatori Java. Man mano che imparano di più, si imbatteranno in situazioni in cui devono essere più perspicaci, come quando si occupano di mappe o database, ma a quel punto dovrebbero anche avere una migliore comprensione della differenza tra i primitivi e i primitivi in ​​scatola.

Autoboxing ci induce a credere che int e Integer (ad esempio) siano intercambiabili, ma è una trappola. Se si mescolano i due tipi di valore in modo indiscriminato, si può finire per confrontare due valori Integer con == o provare a rimuovere un valore null senza rendersene conto. I bug risultanti possono essere intermittenti e difficili da rintracciare.

Non aiuta il confronto tra i primitivi in ​​scatola con == volte funziona come se stesse facendo un confronto di valori. È un'illusione causata dal fatto che i valori all'interno di un certo intervallo vengono automaticamente memorizzati nella cache durante il processo di autoboxing. È lo stesso problema che abbiamo sempre avuto con i valori di stringa: confrontarli con == volte "funziona" perché in realtà stai confrontando due riferimenti allo stesso oggetto memorizzato nella cache.

Quando ci occupiamo di stringhe, possiamo semplicemente dire ai n00bs di non confrontarli con == , come abbiamo sempre fatto. Ma confrontare primitivi con == è perfettamente valido; il trucco (grazie all'autoboxing) è essere certi che i valori siano davvero primitivi. Il compilatore ora ci permetterà di dichiarare una variabile come un Integer e usarla come se fosse un int ; ciò significa che dobbiamo esercitare un maggiore livello di disciplina e trattarlo come un errore quando qualcuno lo fa senza una buona ragione.


Non penso ci sia alcuna regola in quanto tale. Sceglierei i tipi su primitive (Integer su int) quando scrivo firme di metodi, mappe, raccolte, oggetti dati che vengono passati in giro. Come tale mi piacerebbe ancora usare Integer invece di int anche all'interno di metodi ecc. Ma se pensi che sia troppo disturbo (per digitare extra "eger"), allora va bene usare gli inte per le variabili locali.


Penso che sia un po 'tardi ma volevo aggiungere la mia opinione per ogni evenienza.

in alcuni scenari, è necessario utilizzare i wrapper poiché la mancanza di un valore è diversa dal valore predefinito.

Ad esempio, per un progetto su cui ho lavorato, c'era un campo sullo schermo in cui l'utente poteva inserire un doppio valore, il requisito aziendale chiaramente menzionato che se l'utente immette uno 0 il significato è diverso da non immettere un valore e lasciare il campo vuoto e questa differenza avrà un impatto più avanti in un altro modulo. quindi in questo scenario abbiamo dovuto usare l'oggetto Double, dal momento che non posso rappresentare una mancanza di valore usando la primitiva; dal momento che la primitiva sarà impostata su 0, che era un input valido per il campo.


Poiché Java fa qualcosa chiamato auto-boxing e auto-unboxing , nella maggior parte dei casi si dovrebbe usare il tipo primitivo int a causa di un minore overhead.

L'unica volta che devi assolutamente usare Integer è in generici.

List<int> list; // won't compile
List<Integer> list; // correct

Questo dipende molto dal contesto. Prima preferisco il primitivo, perché è più intuitivo e ha meno spese generali. Se non è possibile per motivi generici / autoboxing, o se vuoi che sia annullabile, allora vai per il tipo di wrapper (tipo complesso come lo chiami).


Un caso in cui l' Integer potrebbe essere preferito è quando si lavora con un database in cui le voci numeriche possono essere nulle, dato che non si è in grado di rappresentare un valore nullo con un int .

Ma naturalmente se stai facendo calcoli matematici, allora int sarebbe migliore di quello che altri hanno menzionato a causa dell'intuitività e di un sovraccarico.







reference-type