CodeGym /Kursy /JAVA 25 SELF /Typy opakowujące w Javie

Typy opakowujące w Javie

JAVA 25 SELF
Poziom 10, Lekcja 1
Dostępny

1. Wprowadzenie

W języku Java istnieją dwie różne rodziny danych. Pierwsza – to typy prymitywne: int, char, double, boolean i inne. Są proste i szybkie: wartość jest przechowywana bezpośrednio w komórce pamięci. Druga rodzina – to typy referencyjne, czyli obiekty: zmienna przechowuje referencję do miejsca, w którym obiekt znajduje się w pamięci.

Czasem trzeba użyć prymitywu jak obiektu. Jednak prymitywy z założenia nie są obiektami. W takich sytuacjach pomagają specjalne klasy opakowujące.

Typy opakowujące to klasy, które przechowują w sobie wartość prymitywu i pozwalają traktować ją jak obiekt. Na przykład, dla int — klasa Integer, dla double — Double, dla char — Character, dla boolean — Boolean. Takie klasy udostępniają metody: Integer.parseInt(), Double.isInfinite(), Character.isLetter(), Boolean.parseBoolean() i inne.

Przykład uzyskania obiektu Integer z prymitywu int:

// prymityw
int a = 10;

// obiekt opakowujący
Integer b = Integer.valueOf(10);

W zmiennej a przechowywana jest sama liczba 10. A zmienna b przechowuje referencję do obiektu, który wewnątrz zawiera 10.

2. Po co potrzebne są opakowania

Prymityw to zawsze konkretna wartość, nie można ustawić go na null. Obiekt może nie istnieć i przechowywać pustą wartość – to wygodne, gdy trzeba oznaczyć „nieznane” lub „brak”.

Prymityw nie ma metod. Nie da się wywołać na liczbie czegoś w rodzaju x.toString(). Opakowanie zapewnia takie możliwości: Integer.parseInt("123") zamienia napis na liczbę, a liczbę można zamienić na napis metodą toString().

Podsumowując: opakowania są potrzebne tam, gdzie wymagany jest obiekt – możliwość przechowywania null, wywoływania metod, przekazywania wartości do API, które przyjmuje tylko obiekty (na przykład kolekcje typu List<Integer>).

Pełna lista typów opakowujących

Typ prymitywny Klasa opakowująca
byte
Byte
short
Short
int
Integer
long
Long
float
Float
double
Double
char
Character
boolean
Boolean

3. Pakowanie i rozpakowywanie

Gdy ręcznie tworzysz obiekt-opakowanie, bierzesz prymityw i „pakujesz” go do obiektu:

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

Aby wydobyć z powrotem wartość prymitywną – „rozpakować” – używa się na przykład intValue():

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

Autoboksowanie (Autoboxing)

Kompilator sam doda wywołanie valueOf(), jeśli przypisujesz prymityw do zmiennej-opakowania:

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

Auto-rozpakowywanie (Unboxing)

Sytuacja odwrotna – gdy obiekt-opakowanie używany jest tam, gdzie potrzebny jest prymityw:

Integer c = 20;
int d = c; // auto-rozpakowywanie (c.intValue())

int a = 10; // prymityw
Integer b = a; // autoboksowanie
Integer c = Integer.valueOf(20);
int d = c; // auto-rozpakowywanie
Autoboksowanie i auto-rozpakowywanie

4. Pułapki

Porównywanie opakowań. Operator == dla obiektów porównuje referencje, a nie wartości:

Integer m = 200;
Integer n = 200;
System.out.println(m == n); // false, ponieważ to różne obiekty

Java keszuje opakowania liczb z zakresu od -128 do 127, więc czasem == zwróci true, a czasem – false. Do porównywania wartości zawsze używaj equals():

Integer x = 100;
Integer y = 100;
System.out.println(x == y);      // true, w pamięci podręcznej
System.out.println(x.equals(y)); // true, porównanie wartości

NullPointerException przy auto-rozpakowywaniu. Jeśli opakowanie ma wartość null, a próbujesz je rozpakować – otrzymasz wyjątek:

Integer value = null;
int primitive = value; // Błąd! NullPointerException

Wydajność i pamięć. Opakowania są wolniejsze od prymitywów i zajmują więcej pamięci. W gorących miejscach kodu i przy pracy z dużymi tablicami liczb wybieraj prymitywy.

5. Przykłady

Przykłady pracy z Integer i Double

Konwersja napisu na liczbę:

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

Sprawdzanie szczególnych wartości liczb zmiennoprzecinkowych:

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

Przykłady pracy z Character

char przechowuje jeden znak; opakowanie Character udostępnia wygodne sprawdzenia:

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

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

Przykłady pracy z Boolean

Prymityw boolean — to tylko true/false. Opakowanie Boolean pozwala przechowywać także null:

Boolean flag = null; // dozwolone
flag = Boolean.TRUE; // specjalna stała

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

Konwersja napisów do wartości logicznych:

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
1
Zadanie
JAVA 25 SELF, poziom 10, lekcja 1
Niedostępne
Zapis punktów gracza 🎮
Zapis punktów gracza 🎮
1
Zadanie
JAVA 25 SELF, poziom 10, lekcja 1
Niedostępne
Sprawdzenie wprowadzenia cyfry 🔢
Sprawdzenie wprowadzenia cyfry 🔢
1
Zadanie
JAVA 25 SELF, poziom 10, lekcja 1
Niedostępne
Przekazywanie cen produktów do cyfrowego koszyka 🛒
Przekazywanie cen produktów do cyfrowego koszyka 🛒
1
Zadanie
JAVA 25 SELF, poziom 10, lekcja 1
Niedostępne
Przetwarzanie "uszkodzonych" danych 📉
Przetwarzanie "uszkodzonych" danych 📉
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION