CodeGym /Corsi /JAVA 25 SELF /Classi wrapper in Java

Classi wrapper in Java

JAVA 25 SELF
Livello 10 , Lezione 1
Disponibile

1. Introduzione

Nel linguaggio Java esistono due diverse famiglie di dati. La prima — sono i tipi primitivi: int, char, double, boolean e altri. Sono semplici e veloci: il valore è memorizzato direttamente nella cella di memoria. La seconda famiglia — sono i tipi di riferimento, cioè oggetti: la variabile contiene un riferimento al luogo in cui l'oggetto è situato in memoria.

A volte è necessario usare un primitivo come un oggetto. Ma i primitivi, di per sé, non sono oggetti. In questi casi aiutano le speciali classi wrapper.

I tipi wrapper sono classi che contengono al loro interno il valore di un primitivo e permettono di trattarlo come un oggetto. Ad esempio, per int — la classe Integer, per doubleDouble, per charCharacter, per booleanBoolean. Tali classi forniscono metodi: Integer.parseInt(), Double.isInfinite(), Character.isLetter(), Boolean.parseBoolean() e altri.

Esempio di ottenere un oggetto Integer da un primitivo int:

// Primitivo
int a = 10;

// Oggetto wrapper
Integer b = Integer.valueOf(10);

Nella variabile a è memorizzato il numero 10 stesso. La variabile b invece contiene un riferimento a un oggetto che al suo interno contiene 10.

2. Perché servono i wrapper

Un primitivo è sempre un valore concreto, non può essere uguale a null. Un oggetto può non esistere e contenere un valore vuoto — è comodo quando bisogna indicare «sconosciuto» o «assente».

Un primitivo non ha metodi. Non si può invocare su un numero qualcosa come x.toString(). Un wrapper offre tali possibilità: Integer.parseInt("123") trasforma una stringa in un numero, e un numero può essere convertito in stringa con toString().

In sintesi: i wrapper servono dove è necessario un oggetto — la possibilità di memorizzare null, chiamare metodi, passare valori a un'API che accetta solo oggetti (ad esempio, le collezioni come List<Integer>).

Elenco completo delle classi wrapper

Tipo primitivo Classe wrapper
byte
Byte
short
Short
int
Integer
long
Long
float
Float
double
Double
char
Character
boolean
Boolean

3. Boxing e unboxing

Quando create manualmente un oggetto wrapper, prendete un primitivo e lo «incapsulate» all'interno dell'oggetto:

int primitive = 42;
Integer wrapper = Integer.valueOf(primitive); // boxing

Per recuperare il valore primitivo — fare l'unboxing — si usa, ad esempio, intValue():

Integer wrapper = Integer.valueOf(42);
int primitive = wrapper.intValue(); // unboxing

Autoboxing (Autoboxing)

Il compilatore aggiungerà automaticamente la chiamata a valueOf() se assegnate un primitivo a una variabile wrapper:

int a = 10;
Integer b = a; // autoboxing (Integer.valueOf(a))

Unboxing (Unboxing)

Situazione inversa — quando un oggetto wrapper viene usato dove serve un primitivo:

Integer c = 20;
int d = c; // unboxing (c.intValue())

int a = 10; // primitivo
Integer b = a; // autoboxing
Integer c = Integer.valueOf(20);
int d = c; // unboxing
Autoboxing e unboxing

4. Insidie

Confronto dei wrapper. L'operatore == per gli oggetti confronta i riferimenti, non i valori:

Integer m = 200;
Integer n = 200;
System.out.println(m == n); // false, perché sono oggetti diversi

Java mette in cache i wrapper dei numeri nell'intervallo da -128 a 127, quindi a volte == restituirà true e altre — false. Per confrontare i valori usate sempre equals():

Integer x = 100;
Integer y = 100;
System.out.println(x == y);      // true, rientra nella cache
System.out.println(x.equals(y)); // true, confronto per valore

NullPointerException durante l'unboxing. Se un wrapper è uguale a null e provate a fare l'unboxing — otterrete un'eccezione:

Integer value = null;
int primitive = value; // Errore! NullPointerException

Prestazioni e memoria. I wrapper sono più lenti dei primitivi e occupano più memoria. Nelle parti calde del codice e quando si lavora con grandi array di numeri, scegliete i primitivi.

5. Esempi

Esempi con Integer e Double

Conversione di una stringa in numero:

String text = "123";
int number = Integer.parseInt(text);
System.out.println(number); // 123

Verifica di valori speciali dei numeri in virgola mobile:

double d = 1.0 / 0;
System.out.println(Double.isInfinite(d)); // true

double nan = 0.0 / 0.0;
System.out.println(Double.isNaN(nan)); // true

Esempi con Character

char memorizza un singolo carattere; il wrapper Character offre comode verifiche:

char ch = 'A';
Character wrapper = ch; // autoboxing

System.out.println(Character.isLetter(ch)); // true
System.out.println(Character.isDigit(ch));  // false
System.out.println(Character.toLowerCase(ch)); // 'a'

Esempi con Boolean

Il primitivo boolean è solo true/false. Il wrapper Boolean consente di memorizzare anche null:

Boolean flag = null; // consentito
flag = Boolean.TRUE; // costante speciale

System.out.println(flag); // true

Conversione di stringhe in valori booleani:

String s1 = "true";
String s2 = "false";
boolean b1 = Boolean.parseBoolean(s1);
boolean b2 = Boolean.parseBoolean(s2);

System.out.println(b1); // true
System.out.println(b2); // false
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION