Mi stai chiedendo di tipi e oggetti primitivi, ma non penso che sia una distinzione utile qui. Invece, dovresti pensare ai tipi di riferimento e ai tipi di valore:
-
Tipi di valore : sempre esattamente del tipo specificato (non può essere invece un tipo derivato); non è possibile utilizzare la funzione di invio virtuale; lifetime legato all'ambito della variabile (solitamente allocata nello stack)
-
Tipi di riferimento : può essere il tipo specificato o un tipo derivato; può utilizzare la funzione di invio virtuale; durata non legata all'ambito della variabile (solitamente allocata sullo heap)
Se osservi queste differenze, ti rendi conto che entrambi i tipi hanno alcuni pregi: i tipi di valore sono più performanti, mentre i tipi di riferimento sono più flessibili, specialmente se si desidera utilizzare le funzionalità OOP come ereditarietà o funzioni virtuali.
Questo è il motivo per cui molte lingue (incluso C ++, C # e Java) offrono entrambe in una forma o nell'altra (sebbene la forma sia molto varia).
Ora abbiamo due tipi di tipi, ma vorremmo anche avere un sistema di tipi unificato. E questo significa avere un tipo, in cui le variabili di questo tipo possono contenere valori di qualsiasi tipo. Questo requisito significa che il tipo (chiamato Object
in C # e Java) deve essere un tipo di riferimento. E per convertire un tipo di valore in questo tipo di Object
, devi "box": crea una copia del valore che si comporta come un tipo di riferimento.
Per riassumere: una lingua deve supportare la boxe, se si desidera avere tipi di riferimento, tipi di valore e un sistema di tipi unificato.