Risposte:
Altri hanno menzionato che alcuni costrutti come Collections
require objects e che gli oggetti hanno più overhead rispetto alle loro controparti primitive (memory & boxing).
Un'altra considerazione è:
Può essere utile inizializzare oggetti null
o inviare null
parametri in un metodo / costruttore per indicare lo stato o la funzione. Questo non può essere fatto con le primitive.
Molti programmatori inizializzano i numeri su 0 (impostazione predefinita) o -1 per indicare ciò, ma a seconda dello scenario, ciò potrebbe essere errato o fuorviante.
Questo creerà anche la scena per NullPointerException
quando qualcosa viene usato in modo errato, il che è molto più facile da programmare di qualche bug arbitrario su tutta la linea.
In generale, dovresti usare i tipi primitivi a meno che tu non abbia bisogno di un oggetto per qualche motivo (ad esempio per metterlo in una raccolta). Anche in questo caso, considera un approccio diverso che non richiede un oggetto se desideri massimizzare le prestazioni numeriche. Ciò è consigliato dalla documentazione e questo articolo dimostra come l'auto-boxing possa causare una grande differenza di prestazioni.
Integer
è più leggibile di int
.
A mio parere, se i membri della mia classe sono variabili wrapper, non si basa sui valori predefiniti, che è un comportamento amichevole per gli sviluppatori.
1.
class Person {
int SSN ; // gets initialized to zero by default
}
2.
class PersonBetter {
Integer SSN; //gets initialized to null by default
}
Nel primo caso, non è possibile mantenere il valore SSN non inizializzato. Potrebbe far male se non stai controllando se il valore è stato impostato prima di tentare di usarlo.
Nel secondo caso, puoi mantenere SSN inizializzato con null. Ciò può portare a NullPointerException ma è meglio che inserire inconsapevolmente valori predefiniti (zero) come SSN nel database ogni volta che si tenta di utilizzarlo senza inizializzare il campo SSN.
PersonBuilder
un'eccezione se SSN non è impostato prima di chiamare "build" per ottenere l' Person
istanza. Penso che questo genere di cose sia eccessivo, ma è ciò che il linguaggio Java promuove per i modelli appropriati.
Userei solo i tipi di wrapper se necessario.
Usandoli non guadagni molto, oltre al fatto che lo sono Objects
.
E perdi il sovraccarico nell'utilizzo della memoria e nel tempo trascorso a boxare / unboxing.
Praticamente mi ero imbattuto in una situazione in cui è possibile spiegare l'uso della classe wrapper.
Ho creato una classe di servizio che aveva una long
variabile di tipo
long
- quando non è inizializzata, sarà impostata su 0 - questo creerà confusione per l'utente quando visualizzato nella GUI Long
- quando non è inizializzata, verrà impostata su null
- questo valore nullo non verrà visualizzato nella GUI.Questo vale anche per i casi Boolean
in cui i valori possono essere più confusi quando usiamo primitiva boolean
(poiché il valore predefinito è falso).
Le collezioni sono il caso tipico per i semplici oggetti wrapper Java. Tuttavia, potresti considerare di dare al wrapper un significato più specifico nel codice (oggetto valore).
IMHO c'è quasi sempre un vantaggio nell'usare oggetti valore quando si riduce alla leggibilità e alla manutenzione del codice. Il wrapping di semplici strutture di dati all'interno di oggetti quando hanno determinate responsabilità spesso semplifica il codice. Questo è qualcosa di molto importante nella progettazione guidata dal dominio .
Ovviamente c'è il problema delle prestazioni, ma tendo a ignorarlo fino a quando non ho la possibilità di misurare le prestazioni con dati adeguati e fare azioni più dirette verso l'area problematica. Potrebbe anche essere più semplice comprendere il problema delle prestazioni se anche il codice è di facile comprensione.
le prestazioni di applicazioni dominate da calcoli numerici possono trarre grandi vantaggi dall'uso delle primitive.
tipi primitivi, si usa l'operatore ==, ma per il wrapper la scelta preferita è chiamare il metodo equals ().
"Tipi primitivi considerati dannosi" perché mescolano "semantica procedurale in un modello orientato agli oggetti altrimenti uniforme.
Molti programmatori inizializzano i numeri su 0 (impostazione predefinita) o -1 per indicare ciò, ma a seconda dello scenario, ciò potrebbe essere errato o fuorviante.
Se vuoi usare le collezioni, devi usare le classi wrapper.
I tipi primitivi vengono utilizzati per gli array. Inoltre, per rappresentare dati privi di comportamento, ad esempio un contatore o una condizione booleana.
Dall'autoboxing, la frontiera del "quando usare primitivo o wrapper" è diventata piuttosto confusa.
Ma ricorda, i wrapper sono oggetti, quindi ottieni tutte le fantastiche funzionalità di Java. Ad esempio, puoi usare reflexion per creare oggetti Integer, ma non valori int. Le classi wrapper hanno anche metodi come valueOf.
Se vuoi creare un tipo di valore. Qualcosa come ProductSKU o AirportCode.
Quando un tipo primitivo (stringa nei miei esempi) definisce l'uguaglianza, ti consigliamo di sovrascrivere l'uguaglianza.
I valori primitivi in Java non sono oggetto. Per manipolare questi valori come oggetti, il pacchetto java.lang fornisce una classe wrapper per ciascuno dei tipi di dati primitivi.
Tutte le classi di wrapper sono definitive. L'oggetto di tutte le classi wrapper che possono essere avviate non sono modificabili, il che significa che il valore nell'oggetto wrapper non può essere modificato.
Tuttavia , la classe void è considerata una classe wrapper ma non racchiude alcun valore primitivo e non è inizializzabile. Non ha un costruttore pubblico, denota semplicemente un oggetto classe che rappresenta la parola chiave void.