Autoboxing và unboxing trong java là gì năm 2024

Autoboxing is the automatic conversion that the Java compiler makes between the primitive types and their corresponding object wrapper classes. For example, converting an int to an Integer, a double to a Double, and so on. If the conversion goes the other way, this is called unboxing.

Here is the simplest example of autoboxing:

The rest of the examples in this section use generics. If you are not yet familiar with the syntax of generics, see the Generics (Updated) lesson.

Consider the following code:

List li = new ArrayList<>(); for (int i = 1; i < 50; i += 2)

li.add(i);
Although you add the int values as primitive types, rather than Integer objects, to li, the code compiles. Because li is a list of Integer objects, not a list of int values, you may wonder why the Java compiler does not issue a compile-time error. The compiler does not generate an error because it creates an Integer object from i and adds the object to li. Thus, the compiler converts the previous code to the following at runtime:

List li = new ArrayList<>(); for (int i = 1; i < 50; i += 2)

li.add(Integer.valueOf(i));
Converting a primitive value (an int, for example) into an object of the corresponding wrapper class (Integer) is called autoboxing. The Java compiler applies autoboxing when a primitive value is:

  • Passed as a parameter to a method that expects an object of the corresponding wrapper class.
  • Assigned to a variable of the corresponding wrapper class.

Consider the following method:

public static int sumEven(List li) {

int sum = 0;
for (Integer i: li)
    if (i % 2 == 0)
        sum += i;
    return sum;
}

Because the remainder (%) and unary plus (+=) operators do not apply to Integer objects, you may wonder why the Java compiler compiles the method without issuing any errors. The compiler does not generate an error because it invokes the intValue method to convert an Integer to an int at runtime:

public static int sumEven(List li) {

int sum = 0;
for (Integer i : li)
    if (i.intValue() % 2 == 0)
        sum += i.intValue();
    return sum;
}

Converting an object of a wrapper type (Integer) to its corresponding primitive (int) value is called unboxing. The Java compiler applies unboxing when an object of a wrapper class is:

  • Passed as a parameter to a method that expects a value of the corresponding primitive type.
  • Assigned to a variable of the corresponding primitive type.

The Unboxing example shows how this works:

import java.util.ArrayList; import java.util.List; public class Unboxing {

public static void main(String[] args) {
    Integer i = new Integer(-8);
    // 1. Unboxing through method invocation
    int absVal = absoluteValue(i);
    System.out.println("absolute value of " + i + " = " + absVal);
    List ld = new ArrayList<>();
    ld.add(3.1416);    // Π is autoboxed through method invocation.
    // 2. Unboxing through assignment
    double pi = ld.get(0);
    System.out.println("pi = " + pi);
}
public static int absoluteValue(int i) {
    return (i < 0) ? -i : i;
}
}

The program prints the following:

absolute value of -8 = 8 pi = 3.1416

Autoboxing and unboxing lets developers write cleaner code, making it easier to read. The following table lists the primitive types and their corresponding wrapper classes, which are used by the Java compiler for autoboxing and unboxing:

Phân biệt điểm khác nhau giữa Wrapper Class và Autoboxing trong JAVA. Điểm ít dân lập trình chú ý và thường rất hay nhầm lẫn trong quá trình sử dụng.

Autoboxing và unboxing trong java là gì năm 2024
Wrapper Class và Autoboxing

Chắc chắn rất nhiều bạn lập trình viên JAVA sử dụng hai định nghĩa “Wrapper Class và Autoboxing”. Chúng tôi cam đoan khá nhiều bạn nhầm lẫn giữa chúng. Trung Tâm sẽ đưa ra điểm khác biệt giữa chúng khiến các bạn nhớ mãi không quên.

Wrapper Class và Autoboxing – Cùng Nhau Lập Trình JAVA.

Autoboxing Trong JAVA là gì:

  • Boxing tự chuyển từ kiểu cơ bản sang kiểu đối tượng.
  • Unboxing: Chuyển tử đối tượng thành cơ bản.

Wrappper Class là những Class JAVA định nghĩa ra tương ứng với những kiểu dữ liệu cơ bản.

Để hiểu chi tiết hơn với những lý thuyết trên chúng ta sẽ đi vào thực hành chi tiết. Trung Tâm sẽ quay video màn hình cho các bạn lập trình dễ nhìn và biết cách làm như thế nào.

Trong các phiên bản bên dưới JDK 1.5 , không dễ để chuyển đổi các kiểu dữ liệu nguyên thủy như

int in = 0;
in = new Integer(9);

0,

int in = 0;
in = new Integer(9);

1, sang các lớp trình bao bọc của chúng là Integer, Character, Float, Double. Bắt đầu với JDK 5, chức năng này, chuyển đổi các kiểu nguyên thủy thành các đối tượng tương đương, được triển khai tự động. Thuộc tính này được gọi là Autoboxing . Quá trình ngược lại tương ứng là Unboxing , tức là. quá trình chuyển đổi các đối tượng thành các kiểu nguyên thủy tương ứng của chúng. Mã mẫu cho autoboxing và unboxing được đưa ra dưới đây: Autoboxing

int in = 0;
in = new Integer(9);

2

int in = 0;
in = new Integer(9);

3

Integer integer = 9;

Mở hộp

int in = 0;
in = new Integer(9);

Khi nào việc đóng gói và giải nén tự động được sử dụng? Autoboxing được trình biên dịch Java sử dụng trong các điều kiện sau:

  • Khi một giá trị của kiểu nguyên thủy được truyền cho một phương thức dưới dạng tham số phương thức, phương thức này sẽ có một đối tượng của lớp trình bao bọc tương ứng.
  • Khi một giá trị của kiểu nguyên thủy được gán cho một biến của lớp trình bao bọc tương ứng.

Hãy xem xét ví dụ sau: Liệt kê 1: Mã đơn giản hiển thị hộp thư tự động

public int sumEvenNumbers(List intList ) {
int sum = 0;
for (Integer i: intList )
if ( i % 2 == 0 )
sum += i;
return sum;
}

Trước jdk 1.5, đoạn mã trên có thể đã gây ra lỗi biên dịch vì toán tử còn lại % và dấu cộng += đơn phân không thể được áp dụng cho lớp trình bao bọc. Nhưng trong jdk 1.5 trở lên, mã này biên dịch không có lỗi, chuyển đổi Integer thành

int in = 0;
in = new Integer(9);

0. Việc bỏ hộp được trình biên dịch Java sử dụng theo các điều kiện sau:

Autoboxing và unboxing trong java là gì năm 2024

  • Khi một đối tượng được truyền dưới dạng tham số cho một phương thức có kiểu nguyên thủy tương ứng.
  • Khi một đối tượng được gán cho một biến có kiểu nguyên thủy tương ứng.

Hãy xem xét ví dụ sau: Liệt kê 2: Mã đơn giản hiển thị việc mở hộp

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 doubleList = new ArrayList();
// Автоупаковка через вызов метода
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;
}
}

Tính năng tự động đóng hộp và mở hộp cho phép nhà phát triển viết mã dễ đọc và dễ hiểu. Bảng sau đây hiển thị các kiểu dữ liệu nguyên thủy và các đối tượng bao bọc tương ứng của chúng.

Các loại nguyên thủy Lớp vỏ boolean Boolean byte Byte ký tự Tính cách trôi nổi Trôi nổi int số nguyên dài Dài ngắn Ngắn

Bảng 1: Các kiểu nguyên thủy và các lớp bao bọc tương đương với các toán tử so sánh Tính năng tự động đóng hộp và mở hộp có thể được sử dụng với các toán tử so sánh. Đoạn mã sau minh họa cách điều này xảy ra: Liệt kê 3: Mã mẫu hiển thị tính năng tự động đóng hộp và mở hộp bằng toán tử so sánh

public class BoxedComparator {
  public static void main(String[] args) {
      Integer in = new Integer(25);
      if (in < 35)
          System.out.println("Value of int = " + in);
  }
}

Tự động đóng gói và giải nén khi nạp chồng một phương thức Tự động đóng gói và giải nén được thực hiện khi nạp chồng một phương thức dựa trên các quy tắc sau:

  • Việc mở rộng “đánh bại” việc đóng gói trong tình huống phải lựa chọn giữa việc mở rộng và đóng gói; việc mở rộng là thích hợp hơn.

Liệt kê 4: Mã mẫu cho thấy lợi ích của việc nạp chồng

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);
  }
 }
}

Đầu ra chương trình - loại

int in = 0;
in = new Integer(9);

0

  • Việc mở rộng đánh bại số lượng đối số thay đổi Trong trường hợp nó trở thành sự lựa chọn giữa việc mở rộng và số lượng đối số thay đổi, thì việc mở rộng là thích hợp hơn.

Liệt kê 5: Mã mẫu cho thấy lợi ích của việc nạp chồng

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);
   }
  }

  • Việc đóng gói đánh bại số lượng đối số có thể thay đổi Trong trường hợp nó trở thành sự lựa chọn giữa việc đóng gói và số lượng đối số thay đổi, thì việc đóng gói sẽ thích hợp hơn.

Liệt kê 6: Mã mẫu cho thấy lợi ích của việc nạp chồng

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);
    }
}

Bạn nên ghi nhớ những điều sau khi sử dụng Tự động đóng gói: Như chúng ta biết, mọi tính năng tốt đều có nhược điểm. Bao bì ô tô cũng không ngoại lệ về vấn đề này. Một số lưu ý quan trọng mà nhà phát triển cần lưu ý khi sử dụng tính năng này:

  • Việc so sánh các đối tượng bằng

    int in = 0; in = new Integer(9);

    6toán tử '' có thể gây nhầm lẫn vì nó có thể được áp dụng cho các kiểu và đối tượng nguyên thủy. Khi toán tử này được áp dụng cho các đối tượng, nó thực sự so sánh các tham chiếu đến các đối tượng chứ không phải bản thân các đối tượng đó.

Liệt kê 7: Mã mẫu hiển thị sự so sánh.

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");
      }
   }
}

  • Trộn các đối tượng và kiểu nguyên thủy với các toán tử đẳng thức và quan hệ. Nếu chúng ta so sánh một kiểu nguyên thủy với một đối tượng, thì đối tượng đó sẽ không được đóng hộp, có thể ném

    int in = 0; in = new Integer(9);

    7nếu đối tượng đó

    int in = 0; in = new Integer(9);

    8.
  • Bộ nhớ đệm đối tượng. Phương thức này

    int in = 0; in = new Integer(9);

    9tạo ra một vùng chứa các đối tượng nguyên thủy mà nó lưu trữ. Vì các giá trị được lưu trong bộ đệm trong phạm vi từ -128 đến 127 nên các đối tượng được lưu trong bộ nhớ đệm này có thể hoạt động khác nhau.
  • Suy thoái hiệu suất. Việc tự động đóng hộp hoặc mở hộp làm giảm hiệu suất ứng dụng vì nó tạo ra một đối tượng không mong muốn buộc trình thu gom rác phải chạy thường xuyên hơn.

Nhược điểm của AutoBoxing Mặc dù AutoBoxing có một số ưu điểm nhưng nó có những nhược điểm sau: Liệt kê 8: Mã mẫu hiển thị vấn đề về hiệu suất.

public int sumEvenNumbers(List intList) {
          int sum = 0;
          for (Integer i : intList) {
              if (i % 2 == 0) {
                  sum += i;
              }
          }
         return sum;
   }

Trong phần mã này,

public int sumEvenNumbers(List intList ) {
int sum = 0;
for (Integer i: intList )
if ( i % 2 == 0 )
sum += i;
return sum;
}

0 nó sẽ được mở rộng thành

public int sumEvenNumbers(List intList ) {
int sum = 0;
for (Integer i: intList )
if ( i % 2 == 0 )
sum += i;
return sum;
}

1. Bắt đầu với toán tử '

public int sumEvenNumbers(List intList ) {
int sum = 0;
for (Integer i: intList )
if ( i % 2 == 0 )
sum += i;
return sum;
}

2', JVM bắt đầu mở hộp vì

public int sumEvenNumbers(List intList ) {
int sum = 0;
for (Integer i: intList )
if ( i % 2 == 0 )
sum += i;
return sum;
}

2toán tử '' không thể áp dụng cho đối tượng Integer. Và sau đó kết quả được tự động đóng gói lại. Trước JDK 1.5, các kiểu dữ liệu

int in = 0;
in = new Integer(9);

0và Số nguyên khác nhau. Trong trường hợp nạp chồng phương thức, hai loại này được sử dụng mà không gặp vấn đề gì. Với sự ra đời của tính năng đóng/mở gói tự động, việc này đã trở nên khó khăn hơn. Một ví dụ về điều này là phương thức nạp chồng

public int sumEvenNumbers(List intList ) {
int sum = 0;
for (Integer i: intList )
if ( i % 2 == 0 )
sum += i;
return sum;
}

5trong

public int sumEvenNumbers(List intList ) {
int sum = 0;
for (Integer i: intList )
if ( i % 2 == 0 )
sum += i;
return sum;
}

6. Lớp này

public int sumEvenNumbers(List intList ) {
int sum = 0;
for (Integer i: intList )
if ( i % 2 == 0 )
sum += i;
return sum;
}

6có hai phương thức xóa -

public int sumEvenNumbers(List intList ) {
int sum = 0;
for (Integer i: intList )
if ( i % 2 == 0 )
sum += i;
return sum;
}

8và

public int sumEvenNumbers(List intList ) {
int sum = 0;
for (Integer i: intList )
if ( i % 2 == 0 )
sum += i;
return sum;
}

9. Trong trường hợp này, việc nạp chồng phương thức sẽ không xảy ra và phương thức tương ứng sẽ được gọi với các tham số thích hợp.

Phần kết luận

Autoboxing là một cơ chế để chuyển đổi ngầm các kiểu dữ liệu nguyên thủy thành các lớp (đối tượng) trình bao bọc tương ứng. Trình biên dịch sử dụng phương thức này

int in = 0;
in = new Integer(9);

9để chuyển đổi các kiểu nguyên thủy thành các đối tượng và các phương thức

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 doubleList = new ArrayList();
// Автоупаковка через вызов метода
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;
}
}

1,

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 doubleList = new ArrayList();
// Автоупаковка через вызов метода
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;
}
}

2v.v., để thu được các kiểu nguyên thủy của đối tượng. Autoboxing chuyển đổi kiểu boolean

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 doubleList = new ArrayList();
// Автоупаковка через вызов метода
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;
}
}

3thành Boolean,

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 doubleList = new ArrayList();
// Автоупаковка через вызов метода
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;
}
}

4Byte,

int in = 0;
in = new Integer(9);

1Character,

int in = 0;
in = new Integer(9);

2Float,

int in = 0;
in = new Integer(9);

0Integer,

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 doubleList = new ArrayList();
// Автоупаковка через вызов метода
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;
}
}

8Long,

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 doubleList = new ArrayList();
// Автоупаковка через вызов метода
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;
}
}

9Short. Việc giải nén xảy ra theo hướng ngược lại. Bài báo gốc