0Pricing
Java Academy · Lekcja

Pułapki autoboxingu

Unboxing wartości null i pułapki operatora ==

Pułapki autoboxingu to bezpłatna lekcja Java Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Java Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Java Academy zawiera 4 lekcji w sumie.

Wygoda ma swoje pułapki

Autoboxing upraszcza kod, ale ukrywa konwersje, które mogą prowadzić do zaskakujących błędów. Dwie największe pułapki to rozpakowywanie wartości null oraz porównywanie tożsamości za pomocą ==.

W tej lekcji pokazano, jak uniknąć obu tych problemów.

Pułapka rozpakowywania wartości null

Jeśli klasa opakowująca przechowuje wartość null, a następnie zostanie ona rozpakowana do typu prostego, Java zgłosi wyjątek NullPointerException.

Łatwo to przeoczyć, ponieważ kod wygląda jak zwykłe przypisanie.

public class Main {
    public static void main(String[] args) {
        Integer maybe = null;
        try {
            int value = maybe;
            System.out.println(value);
        } catch (NullPointerException e) {
            System.out.println("Cannot unbox null!");
        }
    }
}

null w operacjach arytmetycznych

Ta pułapka występuje również wewnątrz wyrażeń. Dodanie klasy opakowującej o wartości null najpierw powoduje jej rozpakowanie, które kończy się wyjątkiem, zanim obliczenia w ogóle się rozpoczną.

public class Main {
    public static void main(String[] args) {
        Integer count = null;
        try {
            int total = count + 5;
            System.out.println(total);
        } catch (NullPointerException e) {
            System.out.println("Null in arithmetic!");
        }
    }
}

Ochrona przed wartością null

Przed rozpakowaniem klasy opakowującej należy zawsze sprawdzić, czy nie ma ona wartości null, albo podać wartość domyślną.

public class Main {
    public static void main(String[] args) {
        Integer maybe = null;
        int safe = (maybe != null) ? maybe : 0;
        System.out.println(safe);
    }
}

Zaskoczenie związane z buforowaniem dla ==

Integer.valueOf buforuje wartości z zakresu od -128 do 127. Dlatego dwie opakowane wartości z tego zakresu mogą współdzielić ten sam obiekt, a == zwróci true.

public class Main {
    public static void main(String[] args) {
        Integer a = 100;
        Integer b = 100;
        System.out.println(a == b);
    }
}

Poza zakresem buforowania

Powyżej zakresu buforowania każde opakowanie tworzy odrębny obiekt. W takiej sytuacji == porównuje referencje i zwraca false, mimo że liczby są równe.

public class Main {
    public static void main(String[] args) {
        Integer a = 200;
        Integer b = 200;
        System.out.println(a == b);
    }
}

Zawsze używaj equals

Ponieważ == dla typów opakowujących porównuje tożsamość obiektów, należy używać .equals() do porównywania rzeczywistych wartości liczbowych.

public class Main {
    public static void main(String[] args) {
        Integer a = 200;
        Integer b = 200;
        System.out.println(a.equals(b));
    }
}

Łączenie == z typem prymitywnym

Jeśli jedna ze stron == jest typem prymitywnym, Java automatycznie rozpakowuje typ opakowujący, więc porównanie odbywa się według wartości. Jest to niezawodne, ale nadal może spowodować wyjątek, jeśli typ opakowujący ma wartość null.

public class Main {
    public static void main(String[] args) {
        Integer a = 200;
        int b = 200;
        System.out.println(a == b);
    }
}

Ukryte opakowywanie w pętlach

Zadeklarowanie akumulatora pętli jako typu opakowującego powoduje utworzenie nowego obiektu w każdej iteracji. W poniższym przykładzie użycie Long zamiast long powodowałoby wielokrotne opakowywanie. Należy preferować typ prymitywny.

public class Main {
    public static void main(String[] args) {
        long sum = 0;
        for (int i = 0; i < 1000; i++) {
            sum += i;
        }
        System.out.println(sum);
    }
}

Map get zwraca null

Częsty błąd w praktycznych zastosowaniach: Map.get zwraca null dla brakującego klucza. Rozpakowanie tego wyniku do int powoduje wyjątek. Zamiast tego należy użyć getOrDefault.

import java.util.HashMap;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        Map<String, Integer> scores = new HashMap<>();
        int score = scores.getOrDefault("missing", 0);
        System.out.println(score);
    }
}

Zachowanie bezpieczeństwa

Dwa nawyki zapobiegają większości błędów związanych z automatycznym opakowywaniem: nigdy nie należy rozpakowywać wartości, która może mieć wartość null, oraz zawsze należy porównywać wartości typów opakowujących za pomocą .equals(), a nie ==.

Szybki test

Sprawdź swoją znajomość pułapek automatycznego opakowywania.

Podsumowanie

Poznałeś(-aś) najważniejsze pułapki automatycznego opakowywania:

  • Rozpakowanie typu opakowującego o wartości null powoduje wyjątek NullPointerException
  • Należy stosować sprawdzanie wartości null lub wartość domyślną
  • == dla typów opakowujących porównuje referencje, a buforowanie obejmuje zakres od -128 do 127
  • Do porównywania wartości należy zawsze używać .equals()
  • Należy używać getOrDefault, aby uniknąć wartości null podczas wyszukiwania w mapie

Często zadawane pytania

Czy lekcja „Pułapki autoboxingu” jest bezpłatna?

Tak — pełny tekst „Pułapki autoboxingu” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Java Academy, przejdź na CoddyKit PRO. Kurs Java Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Pułapki autoboxingu”?

Unboxing wartości null i pułapki operatora == Ćwiczysz Java Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Java Academy?

Nie wymagamy żadnego doświadczenia. Java Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Pułapki autoboxingu”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Java Academy?

Tak. Każda lekcja Java Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Typy prymitywne a opakowujące
  2. Autoboxing i unboxing
  3. Parsowanie i valueOf
  4. Pułapki autoboxingu
← Powrót do Java Academy