Introduzione ai Wrapper di tipo in Java
- I wrapper di tipo in Java sono classi che incapsulano i tipi primitivi in oggetti, consentendo di utilizzare i tipi primitivi in contesti che richiedono oggetti.
- I wrapper di tipo principali sono
Character
,Boolean
,Byte
,Short
,Integer
,Long
,Float
eDouble
. - I wrapper di tipo forniscono metodi per convertire tra tipi primitivi e oggetti, come
charValue()
,booleanValue()
,intValue()
, e così via. - A partire da JDK 9, i costruttori dei wrapper di tipo sono stati deprecati e si raccomanda di utilizzare il metodo statico
valueOf()
per ottenere un oggetto wrapper. - Il processo di incapsulamento di un valore all'interno di un oggetto è chiamato boxing, mentre il processo di estrazione di un valore da un wrapper è chiamato unboxing.
Wrapper di Tipo
Come abbiamo visto, Java utilizza tipi primitivi (chiamati anche tipi semplici), come int o double, per contenere i tipi di dati di base supportati dal linguaggio.
I tipi primitivi, piuttosto che gli oggetti, sono utilizzati per queste quantità per ragioni di prestazioni. Utilizzare oggetti (anziché tipi primitivi) per questi valori aggiungerebbe un overhead inaccettabile anche ai calcoli più semplici. Pertanto, i tipi primitivi non fanno parte della gerarchia degli oggetti e non derivano da Object
.
Nonostante il beneficio in termini di prestazioni offerto dai tipi primitivi, ci sono momenti in cui si può avere bisogno di una rappresentazione ad oggetto. Ad esempio, non si può passare un tipo primitivo per riferimento a un metodo.
Inoltre, molte delle strutture dati standard implementate da Java operano su oggetti, il che significa che non si possono utilizzare queste strutture dati per memorizzare tipi primitivi.
Per gestire queste (e altre) situazioni, Java fornisce i cosiddetti wrapper di tipo, che sono classi che incapsulano un tipo primitivo all'interno di un oggetto. Analizzeremo nel dettaglio i wrapper di tipo nelle prossime lezioni. Tuttavia li introduciamo in questa lezione qui perché si riferiscono direttamente alla funzionalità di autoboxing di Java che vedremo nella prossima lezione.
I wrapper di tipo sono Double
, Float
, Long
, Integer
, Short
, Byte
, Character
e Boolean
. Queste classi offrono un'ampia gamma di metodi che permettono di integrare completamente i tipi primitivi nella gerarchia degli oggetti di Java. Ciascuna è brevemente esaminata di seguito.
Il Wrapper Character
Character
è un wrapper attorno a un char
. Il costruttore per Character
è
Character(char ch)
Qui, ch
specifica il carattere che sarà incapsulato dall'oggetto Character
che viene creato.
Tuttavia, a partire da JDK 9, il costruttore Character
è stato deprecato, e a partire da JDK 16, è stato deprecato per la rimozione. Oggi, è fortemente raccomandato utilizzare il metodo statico valueOf()
per ottenere un oggetto Character
. È mostrato qui:
static Character valueOf(char ch)
Restituisce un oggetto Character
che incapsula ch
.
Per ottenere il valore char
contenuto in un oggetto Character
, chiamare charValue()
, mostrato qui:
char charValue()
Restituisce il carattere incapsulato.
Il Wrapper Boolean
Boolean
è un wrapper attorno ai valori boolean
. Definisce questi costruttori:
Boolean(boolean *valoreBool*)
Boolean(String *stringaBool*)
Nella prima versione, valoreBool
deve essere true
o false
. Nella seconda versione, se stringaBool
contiene la stringa "true"
(in maiuscolo o minuscolo), allora il nuovo oggetto Boolean
sarà true. Altrimenti, sarà false.
Tuttavia, a partire da JDK 9, i costruttori Boolean
sono stati deprecati, e a partire da JDK 16, sono stati deprecati per la rimozione. Oggi, è fortemente raccomandato utilizzare il metodo statico valueOf()
per ottenere un oggetto Boolean
. Ha le due versioni mostrate qui:
static Boolean valueOf(boolean *valoreBool*)
static Boolean valueOf(String *stringaBool*)
Ognuna restituisce un oggetto Boolean
che racchiude il valore indicato.
Per ottenere un valore boolean
da un oggetto Boolean
, utilizzare booleanValue()
, mostrato qui:
boolean booleanValue()
Restituisce l'equivalente boolean
dell'oggetto che lo invoca.
I Wrapper per i Tipi Numerici
Di gran lunga, i wrapper per i tipi più comunemente utilizzati sono quelli che rappresentano valori numerici.
Questi sono Byte
, Short
, Integer
, Long
, Float
, e Double
.
Tutti i wrapper per i tipi numerici ereditano dalla classe astratta Number
. Number
dichiara metodi che restituiscono il valore di un oggetto in ciascuno dei diversi formati numerici. Questi metodi sono mostrati qui:
byte byteValue()
double doubleValue()
float floatValue()
int intValue()
long longValue()
short shortValue()
Per esempio, doubleValue()
restituisce il valore di un oggetto come un double
, floatValue()
restituisce il valore come un float
, e così via. Questi metodi sono implementati da ciascuno dei wrapper per i tipi numerici.
Tutti i wrapper per i tipi numerici definiscono costruttori che permettono di costruire un oggetto da un valore dato, o da una rappresentazione stringa di quel valore. Per esempio, ecco i costruttori definiti per Integer
:
Integer(int *num*)
Integer(String *str*)
Se str
non contiene un valore numerico valido, allora viene lanciata una NumberFormatException
.
Tuttavia, a partire da JDK 9, i costruttori dei wrapper per i tipi numerici sono stati deprecati, e a partire da JDK 16, sono stati deprecati per la rimozione. Oggi, è fortemente raccomandato utilizzare uno dei metodi valueOf()
per ottenere un oggetto wrapper. Il metodo valueOf()
è un membro statico di tutte le classi wrapper numeriche e tutte le classi numeriche supportano forme che convertono un valore numerico o una stringa in un oggetto. Per esempio, ecco due delle forme supportate da Integer
:
static Integer valueOf(int val)
static Integer valueOf(String valStr) throws NumberFormatException
Qui, val
specifica un valore intero e valStr
specifica una stringa che rappresenta un valore numerico correttamente formattato in forma stringa. Ciascuno restituisce un oggetto Integer
che avvolge il valore specificato. Ecco un esempio:
Integer iOb = Integer.valueOf(100);
Dopo che questa istruzione viene eseguita, il valore 100 è rappresentato da un'istanza Integer
. Così, iOb
avvolge il valore 100 all'interno di un oggetto. Oltre alle forme di valueOf()
appena mostrate, i wrapper per gli interi, Byte
, Short
, Integer
, e Long
, forniscono anche una forma che ti permette di specificare una base.
Tutti i wrapper per i tipi sovrascrivono toString()
. Restituisce la forma leggibile dall'uomo del valore contenuto all'interno del wrapper. Questo ti permette di output il valore passando un oggetto wrapper per i tipi a println()
, per esempio, senza dover convertirlo nel suo tipo primitivo.
Il seguente programma dimostra come utilizzare un wrapper per i tipi numerici per incapsulare un valore e poi estrarre quel valore.
// Dimostra un wrapper per i tipi.
class EsempioWrapper {
public static void main(String[] args) {
Integer iOb = Integer.valueOf(100);
int i = iOb.intValue();
System.out.println(i + " " + iOb); // visualizza 100 100
}
}
Questo programma avvolge il valore intero 100 all'interno di un oggetto Integer
chiamato iOb
. Il programma poi ottiene questo valore chiamando intValue()
e memorizza il risultato in i
.
Il processo di incapsulamento di un valore all'interno di un oggetto è chiamato boxing. Così, nel programma, questa linea fa il boxing del valore 100 in un Integer
:
Integer iOb = Integer.valueOf(100);
Il processo di estrazione di un valore da un wrapper per i tipi è chiamato unboxing. Per esempio, il programma fa l'unboxing del valore in iOb
con questa istruzione:
int i = iOb.intValue();
La stessa procedura generale utilizzata dal programma precedente per fare il boxing e l'unboxing dei valori è stata disponibile per l'uso fin dalla versione originale di Java.
Tuttavia, oggi, Java fornisce un approccio più semplificato, che vedremo nella prossima lezione: l'autoboxing.