JavaRush /Blog Java /Random-VI /Tự động đóng hộp và mở hộp trong Java
DSergey_Kh
Mức độ

Tự động đóng hộp và mở hộp trong Java

Xuất bản trong nhóm
Trong bài này chúng ta sẽ xem xét một tính năng trong Java có tên là autoboxing/unboxing . Autoboxing và unboxing là chức năng chuyển đổi kiểu nguyên thủy thành kiểu đối tượng và ngược lại. Autoboxing và unboxing trong Java - 1Toàn bộ quá trình được thực hiện tự động bởi Môi trường chạy thi hành Java (JRE). Nhưng bạn nên cẩn thận khi thực hiện chức năng này, bởi vì... Nó có thể ảnh hưởng đến hiệu suất của chương trình của bạn.

Giới thiệu

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, char, 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: Autoboxingfloatdouble
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<Integer> 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. Việc bỏ hộp được trình biên dịch Java sử dụng theo các điều kiện sau:
  • 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<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;
}
}
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ạiint
  • 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 ==toá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 NullPointerExceptionnếu đối tượng đó null.
  • Bộ nhớ đệm đối tượng. Phương thức này valueOf()tạ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, sum +=i nó sẽ được mở rộng thành sum = sum + i. Bắt đầu với toán tử ' +', JVM bắt đầu mở hộp vì +toá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 intvà 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 remove()trong ArrayList. Lớp này ArrayListcó hai phương thức xóa - remove(index)remove(object). 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 valueOf()để 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 IntValue(), doubleValue()v.v., để thu được các kiểu nguyên thủy của đối tượng. Autoboxing chuyển đổi kiểu boolean booleanthành Boolean, byteByte, charCharacter, floatFloat, intInteger, longLong, shortShort. Việc giải nén xảy ra theo hướng ngược lại. Bài báo gốc
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION