JavaRush /Blog Java /Random-PL /Autoboxing i unboxing w Javie
DSergey_Kh
Poziom 12

Autoboxing i unboxing w Javie

Opublikowano w grupie Random-PL
W tym artykule przyjrzymy się funkcji w Javie zwanej autoboxingiem/unboxingiem . Automatyczne pakowanie i rozpakowywanie to funkcje konwersji typów pierwotnych na typy obiektowe i odwrotnie. Autoboxing i unboxing w Javie - 1Cały proces jest wykonywany automatycznie przez środowisko Java Runtime Environment (JRE). Ale należy zachować ostrożność podczas wdrażania tej funkcji, ponieważ... Może to mieć wpływ na wydajność programu.

Wstęp

intW wersjach poniżej JDK 1.5 konwersja prymitywnych typów danych, takich jak , char, float, doublena ich klasy opakowania Integer, Character, Float, Double nie była łatwa . Począwszy od JDK 5, ta funkcjonalność, konwertująca typy pierwotne na równoważne obiekty, jest implementowana automatycznie. Ta właściwość jest znana jako Autoboxing . Procesem odwrotnym jest odpowiednio Unboxing , czyli rozpakowywanie. proces przekształcania obiektów w odpowiadające im typy pierwotne. Przykładowy kod do automatycznego pakowania i rozpakowywania znajduje się poniżej: Autoboxing
Integer integer = 9;
Rozpakowywanie
int in = 0;
in = new Integer(9);
Kiedy stosuje się automatyczne pakowanie i rozpakowywanie? Autoboxing jest używany przez kompilator Java pod następującymi warunkami:
  • Gdy wartość typu pierwotnego jest przekazywana do metody jako parametr metody, która oczekuje obiektu odpowiedniej klasy opakowania.
  • Gdy wartość typu pierwotnego jest przypisana do zmiennej odpowiedniej klasy opakowania.
Rozważmy następujący przykład: Listing 1: Prosty kod pokazujący autoboxing
public int sumEvenNumbers(List<Integer> intList ) {
int sum = 0;
for (Integer i: intList )
if ( i % 2 == 0 )
sum += i;
return sum;
}
Przed wersją jdk 1.5 powyższy kod powodowałby błąd kompilacji, ponieważ nie można było zastosować pozostałego operatora % i unary plus += do klasy opakowania. Ale w jdk 1.5 i nowszych wersjach ten kod kompiluje się bez błędów, konwertując liczbę całkowitą na int. Unboxing jest używany przez kompilator Java pod następującymi warunkami:
  • Gdy obiekt jest przekazywany jako parametr do metody, która oczekuje odpowiedniego typu pierwotnego.
  • Gdy obiekt jest przypisany do zmiennej odpowiedniego typu pierwotnego.
Rozważmy następujący przykład: Listing 2: Prosty kod pokazujący rozpakowywanie
import java.util.ArrayList;
import java.util.List;

public class UnboxingCheck {

public static void main(String[] args) {
Integer in = new Integer(-8);

// 1. Распаковка через вызов метода
int absVal = absoluteValue(in);
System.out.println("absolute value of " + in + " = " + absVal);

List<Double> doubleList = new ArrayList<Double>();

// Автоупаковка через вызов метода
doubleList.add(3.1416);

// 2. Распаковка через присвоение
double phi = doubleList.get(0);
System.out.println("phi = " + phi);
}

public static int absoluteValue(int i) {
return (i < 0) ? -i : i;
}
}
Autoboxing i unboxing pozwala programiście napisać kod, który jest łatwy do odczytania i zrozumienia. W poniższej tabeli przedstawiono podstawowe typy danych i odpowiadające im obiekty opakowania.
Typy pierwotne Klasy powłoki
wartość logiczna Wartość logiczna
bajt Bajt
zwęglać Postać
platforma Platforma
wew Liczba całkowita
długi Długi
krótki Krótki
Tabela 1: Typy pierwotne i równoważne klasy opakowań z operatorami porównania W przypadku operatorów porównania można używać funkcji automatycznego pakowania i rozpakowywania. Poniższy fragment kodu ilustruje, jak to się dzieje: Listing 3: Przykładowy kod pokazujący automatyczne pakowanie i rozpakowywanie za pomocą operatora porównania
public class BoxedComparator {
  public static void main(String[] args) {
      Integer in = new Integer(25);
      if (in < 35)
          System.out.println("Value of int = " + in);
  }
}
Autopakowanie i rozpakowywanie przy przeciążaniu metody Autopakowanie i rozpakowywanie odbywa się przy przeciążaniu metody w oparciu o następujące zasady:
  • Ekspansja „pokonuje” opakowanie w sytuacji, gdy istnieje wybór pomiędzy ekspandowaniem a pakowaniem; preferowane jest ekspandowanie.
Listing 4: Przykładowy kod pokazujący korzyści z przeciążenia
public class WideBoxed {
  public class WideBoxed {
  static void methodWide(int i) {
       System.out.println("int");
   }

  static void methodWide( Integer i ) {
      System.out.println("Integer");
  }

  public static void main(String[] args) {
      short shVal = 25;
      methodWide(shVal);
  }
 }
}
Dane wyjściowe programu - typint
  • Rozszerzanie pokonuje zmienną liczbę argumentów. W sytuacji, gdy staje się wyborem między rozwinięciem a zmienną liczbą argumentów, preferowane jest rozwinięcie.
Listing 5: Przykładowy kod pokazujący korzyści z przeciążenia
public class WideVarArgs {

    static void methodWideVar(int i1, int i2) {
      System.out.println("int int");
    }

    static void methodWideVar(Integer... i) {
       System.out.println("Integers");
    }

   public static void main( String[] args) {
       short shVal1 = 25;
      short shVal2 = 35;
     methodWideVar( shVal1, shVal2);
   }
  }
  • Pakowanie przewyższa zmienną liczbę argumentów. W sytuacji, gdy staje się wyborem pomiędzy pakowaniem a zmienną liczbą argumentów, preferowane jest pakowanie.
Listing 6: Przykładowy kod pokazujący korzyści z przeciążenia
public class BoxVarargs {
     static void methodBoxVar(Integer in) {
         System.out.println("Integer");
     }

     static void methodBoxVar(Integer... i) {
         System.out.println("Integers");
     }
     public static void main(String[] args) {
         int intVal1 = 25;
         methodBoxVar(intVal1);
    }
}
Korzystając z automatycznego pakowania, powinieneś pamiętać o następujących kwestiach: Jak wiemy, każda dobra funkcja ma wadę. Automatyczne pakowanie nie jest pod tym względem wyjątkiem. Kilka ważnych uwag, o których programista powinien pamiętać podczas korzystania z tej funkcji:
  • Porównywanie obiektów za pomocą ==operatora „” może być mylące, ponieważ można go zastosować do pierwotnych typów i obiektów. Gdy ten operator zostanie zastosowany do obiektów, w rzeczywistości porównuje odniesienia do obiektów, a nie do samych obiektów.
Listing 7: Przykładowy kod pokazujący porównanie.
public class Comparator {
   public static void main(String[] args) {
     Integer istInt = new Integer(1);
       Integer secondInt = new Integer(1);

       if (istInt == secondInt) {
         System.out.println("both one are equal");

       } else {
          System.out.println("Both one are not equal");
      }
   }
}
  • Mieszanie obiektów i typów pierwotnych za pomocą operatorów równości i relacyjnych. Jeśli porównamy typ pierwotny z obiektem, wówczas obiekt zostanie rozpakowany, co może wyrzucić, NullPointerExceptionjeśli obiekt null.
  • Buforowanie obiektów. Metoda valueOf()tworzy kontener prymitywnych obiektów, które buforuje. Ponieważ wartości są buforowane w zakresie od -128 do 127 włącznie, te buforowane obiekty mogą zachowywać się inaczej.
  • Obniżenie wydajności. Automatyczne pakowanie lub rozpakowywanie obniża wydajność aplikacji, ponieważ tworzy niechciany obiekt, który wymusza częstsze działanie modułu zbierającego elementy bezużyteczne.
Wady AutoBoxingu Chociaż AutoBoxing ma wiele zalet, ma następujące wady: Listing 8: Przykładowy kod pokazujący problem z wydajnością.
public int sumEvenNumbers(List intList) {
          int sum = 0;
          for (Integer i : intList) {
              if (i % 2 == 0) {
                  sum += i;
              }
          }
         return sum;
   }
W tej części kodu sum +=i zostanie on rozwinięty do sum = sum + i. Zaczynając od +operatora „”, JVM rozpoczyna rozpakowywanie, ponieważ +operatora „” nie można zastosować do obiektu typu Integer. Następnie wynik jest automatycznie pakowany z powrotem. Przed JDK 1.5 typy danych inti liczby całkowite były inne. W przypadku przeciążenia metod te dwa typy były stosowane bez problemów. Wraz z pojawieniem się automatycznego pakowania/rozpakowywania stało się to trudniejsze. Przykładem tego jest przeciążona metoda remove()w ArrayList. Klasa ArrayListma dwie metody usuwania - remove(index)i remove(object). W takim przypadku nie nastąpi przeciążenie metody i zostanie wywołana odpowiednia metoda z odpowiednimi parametrami.

Wniosek

Autoboxing to mechanizm niejawnego konwertowania prymitywnych typów danych na odpowiadające im klasy opakowania (obiekty). Kompilator używa metody valueOf()do konwersji typów pierwotnych na obiekty, a metod itp IntValue(). doubleValue()do uzyskania typów pierwotnych obiektu. Autoboxing konwertuje typ boolowski booleanna logiczny, bytena bajt, charna znak, floatna zmiennoprzecinkowy, intna liczbę całkowitą, longna długi, shortna krótki. Rozpakowanie następuje w odwrotnym kierunku. Oryginalny artykuł
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION