JavaRush /Blog Java /Random-VI /50 câu hỏi và câu trả lời phỏng vấn cốt lõi về Java hàng ...
Roman Beekeeper
Mức độ

50 câu hỏi và câu trả lời phỏng vấn cốt lõi về Java hàng đầu. Phần 2

Xuất bản trong nhóm
50 câu hỏi và câu trả lời phỏng vấn cốt lõi về Java hàng đầu. Phần 1 50 câu hỏi và câu trả lời phỏng vấn cốt lõi về Java hàng đầu.  Phần 2 - 1

Bộ sưu tập

25. Bộ sưu tập trong Java có nghĩa là gì?

Bộ sưu tập là một khung được thiết kế để lưu trữ và thao tác với các đối tượng. Dùng để thực hiện các thao tác sau:
  • tìm kiếm;
  • phân loại;
  • thao tác;
  • phép cộng;
  • xóa.
Tất cả các lớp và giao diện cho khung Bộ sưu tập đều có trong java.utilgói.

26. Những lớp và giao diện nào có sẵn trong khung Bộ sưu tập?

Giao diện:
  • Bộ sưu tập;
  • Danh sách;
  • Bộ;
  • Bản đồ;
  • Bộ sắp xếp;
  • Bản đồ được sắp xếp;
  • Xếp hàng.
Các lớp học:
  • Danh sách:
    1. Lập danh sách;
    2. Danh sách liên kết;
    3. Vector (không dùng nữa).
  • Bộ:
    1. Bộ băm;
    2. LinkedHashSet;
    3. Bộ cây.
  • Bản đồ:
    1. Bản đồ băm
    2. Bản đồ cây
    3. HashTable (không dùng nữa)
    4. Bản đồ LinkedHash
  • Xếp hàng
    1. Hàng đợi ưu tiên.

27. Việc sắp xếp và sắp xếp theo bộ sưu tập có nghĩa là gì?

Ra lệnh:

Điều này có nghĩa là các mục được lưu trữ trong bộ sưu tập dựa trên các giá trị được thêm vào bộ sưu tập. Bằng cách này, chúng ta có thể lặp qua các giá trị từ bộ sưu tập theo một thứ tự cụ thể. Nói cách khác, điều này có nghĩa là các thành phần của bộ sưu tập có thứ tự cụ thể riêng mà chúng được sắp xếp. Để hiểu rõ hơn, một bộ sưu tập không được sắp xếp sẽ lưu trữ các phần tử của nó theo thứ tự ngẫu nhiên. Ví dụ: Đặt.

Đã sắp xếp:

Điều này có nghĩa là một nhóm phần tử được sắp xếp thành một bộ sưu tập dựa trên dữ liệu của phần tử bộ sưu tập. Nghĩa là, không chỉ bộ sưu tập được sắp xếp theo thứ tự mà thứ tự của các phần tử cũng phụ thuộc vào giá trị của chúng. Thứ tự này có thể thay đổi nếu bạn sắp xếp theo giá trị phần tử khác.

28. Có những bộ sưu tập nào có giao diện Danh sách? Bạn làm việc với Danh sách như thế nào?

Giá trị của các phần tử trong trang tính dựa trên chỉ mục của chúng—chúng được sắp xếp theo chỉ mục. Cho phép lặp lại các phần tử (nghĩa là bạn có thể thêm cùng một đối tượng vào bộ sưu tập nhiều lần và sẽ ổn thôi).

Lập danh sách:

Bộ sưu tập phổ biến nhất. Về cơ bản, nó là một mảng có kích thước mở rộng linh hoạt. Công việc quản lý kích thước của mảng thuộc về bộ sưu tập. Điều quan trọng là chúng ta phải hiểu rằng trong hầu hết các trường hợp, đây là thứ chúng ta cần sử dụng. Đặc điểm:
  • tìm kiếm nhanh và tìm kiếm chỉ mục nhanh chóng;
  • bộ sưu tập được sắp xếp theo chỉ mục nhưng không được sắp xếp;
  • triển khai giao diện RandomAccess;
  • từ từ thêm vào giữa danh sách.
Ví dụ:
public class A {

   public static void main(String[] args) {
       ArrayList names = new ArrayList<>();
       names.add("John");
       names.add("John");
       names.add("Roman");
       names.add("Ivan");
   }

}
>> đầu ra

   [John, John, Roman, Ivan]
Kết quả đầu ra cho thấy đây là những phần tử có thể lặp lại. Chúng được hiển thị theo thứ tự mà chúng được ghi lại. Còn gì để đọc nữa? Có, có rất nhiều thông tin, bạn thậm chí không cần rời khỏi JavaRush:

Danh sách liên kết:

Đây là một bộ sưu tập trong đó mỗi phần tử có một liên kết đến các phần tử trước và phần tử tiếp theo. Các liên kết này cho phép bạn di chuyển từ phần tử này sang phần tử khác. Khi thêm một phần tử, các liên kết đến phần tử trước và phần tử tiếp theo chỉ thay đổi: 50 câu hỏi và câu trả lời phỏng vấn cốt lõi về Java hàng đầu.  Phần 2 - 2
  • các phần tử được kết nối với nhau, nghĩa là một danh sách liên kết kép được triển khai;
  • tốc độ hoạt động tổng thể thấp hơn đáng kể so với ArrayList;
  • một sự lựa chọn tuyệt vời cho một số lượng lớn các thao tác chèn và xóa vào giữa một mảng;
  • triển khai các giao diện danh sách Queue và Deque và do đó có các phương thức làm việc của chúng.
Ví dụ:
LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("One");
linkedList.add("Two");
linkedList.add("Three");

29. Hãy cho chúng tôi biết về bộ sưu tập Bản đồ và cách triển khai nó?

Bản đồ là một bộ sưu tập khóa-giá trị. Có một khóa duy nhất và một giá trị khớp với giá trị đó. equals()Các phương pháp cũng được sử dụng hashcode()để xác định tính duy nhất của khóa.

Bản đồ băm:

  • không được sắp xếp, đặt hàng;
  • được sử dụng nếu thứ tự và phân loại không quan trọng;
  • hỗ trợ phím null.
Ví dụ:
public class CollectionExample {

   public static void main(String[] args) {
       HashMap positions = new HashMap<>();
       positions.put("junior", "Ivan");
       positions.put("middle", "Roman");
       positions.put("senior", "Vasily");
       positions.put("team lead", "Anton");
       positions.put("arthitect", "Andrew");
       positions.put("senior", "John");
       System.out.println(positions);
   }
}

// вывод в консоль
// {junior=Ivan, middle=Roman, senior=John, team lead=Anton, arthitect=Andrew}
Các khóa luôn là duy nhất nên chỉ có một cấp cao được ghi lại.

Bản đồ LinkedHash:

  • duy trì thứ tự chèn;
  • chậm hơn HashMap;
  • lặp lại dự kiến ​​​​sẽ nhanh hơn trong HashMap.
Ví dụ:
public class CollectionExample {

   public static void main(String[] args) {
       LinkedHashMap<String, String> positions = new LinkedHashMap<>();
       positions.put("junior", "Ivan");
       positions.put("middle", "Roman");
       positions.put("senior", "Vasily");
       positions.put("team lead", "Anton");
       positions.put("arthitect", "Andrew");
       positions.put("senior", "John");
       System.out.println(positions);
   }
}

// вывод в консоль
// {junior=Ivan, middle=Roman, senior=John, team lead=Anton, arthitect=Andrew}

Bản đồ cây:

Việc triển khai bản đồ giúp giữ các mục được sắp xếp theo thứ tự tự nhiên của các khóa của chúng hoặc tốt hơn là sử dụng bộ so sánh nếu một bộ so sánh được cung cấp trong hàm tạo khi bản đồ được tạo. Ví dụ:
  1. Không có bộ so sánh

    public class CollectionExample {
    
       public static void main(String[] args) {
           TreeMap<Integer, String> positions = new TreeMap<>();
           positions.put(1, "Ivan");
           positions.put(3, "Roman");
           positions.put(2, "Vasily");
           positions.put(10, "Anton");
           positions.put(7, "Andrew");
           positions.put(1, "John");
           System.out.println(positions);
       }
    }
    
    // вывод в консоль
    // {1=John, 2=Vasily, 3=Roman, 7=Andrew, 10=Anton}
  2. Với bộ so sánh

    public class CollectionExample {
    
       public static void main(String[] args) {
           //используем реализацию Strategy Pattern'a и добавим компаратор:
           TreeMap<Integer, String> positions = new TreeMap<>(Comparator.reverseOrder());
           positions.put(1, "Ivan");
           positions.put(3, "Roman");
           positions.put(2, "Vasily");
           positions.put(10, "Anton");
           positions.put(7, "Andrew");
           positions.put(1, "John");
           System.out.println(positions);
       }
    }
    
    // вывод в консоль
    // {10=Anton, 7=Andrew, 3=Roman, 2=Vasily, 1=John}
Chúng tôi thấy rằng việc sắp xếp theo thứ tự tăng dần được triển khai theo tiêu chuẩn, nhưng điều này có thể được thay đổi bằng cách thêm bộ so sánh vào hàm tạo. TreeMap được mô tả rõ ràng ở đây .

30. Hãy cho chúng tôi biết về bộ sưu tập Set và cách triển khai nó?

Set là một tập hợp các phần tử độc đáo và đây là tính năng chính của nó. Tức là Set không cho phép lặp lại các phần tử giống nhau. Điều quan trọng ở đây là các đối tượng được thêm vào phải có phương thức được triển khai equals .

Bộ băm:

  • không được sắp xếp hoặc đặt hàng. Dưới mui xe có HashMap với phần giữ chỗ cho giá trị. Hãy tự mình xem ;)
  • sử dụng hashCode để thêm đối tượng;
  • Nó nên được sử dụng khi bạn cần có các đối tượng duy nhất và thứ tự của chúng không quan trọng.
Ví dụ:
public class CollectionExample {

   public static void main(String[] args) {
       HashSet<String> positions = new HashSet<>();
       positions.add("junior");
       positions.add("junior");
       positions.add("middle");
       positions.add("senior");
       positions.add("team lead");
       positions.add("architect");
       System.out.println(positions);
   }
}

// вывод в консоль
// [senior, middle, team lead, architect, junior]
Ở đây bạn có thể thấy rằng phần tử “junior”, được thêm hai lần, chỉ xuất hiện trong một phiên bản duy nhất. Và thứ tự cũng không giống như khi thêm vào.

LinkedHashSet:

  • phiên bản được đặt hàng của HashSet;
  • hỗ trợ danh sách liên kết đôi cho tất cả các phần tử;
  • sử dụng nó khi cần có sự ngăn nắp trong quá trình lặp lại.
Ví dụ:
public class CollectionExample {

   public static void main(String[] args) {
       LinkedHashSet<String> positions = new LinkedHashSet<>();
       positions.add("junior");
       positions.add("junior");
       positions.add("middle");
       positions.add("senior");
       positions.add("team lead");
       positions.add("architect");
       System.out.println(positions);
   }
}

// вывод в консоль
// [senior, middle, team lead, architect, junior]

Bộ cây:

  • một trong hai bộ sưu tập được sắp xếp;
  • sử dụng cấu trúc cây đỏ đen và đảm bảo rằng các phần tử theo thứ tự tăng dần;
  • Dưới mui xe, đó là TreeMap với phần sơ khai về các giá trị. Và các phần tử của TreeSet chính là chìa khóa của TreeMap (xem thêm ;)).
Ví dụ:
public class CollectionExample {

   public static void main(String[] args) {
       TreeSet<String> positions = new TreeSet<>();
       positions.add("junior");
       positions.add("junior");
       positions.add("middle");
       positions.add("senior");
       positions.add("team lead");
       positions.add("architect");
       System.out.println(positions);
   }
}

// вывод в консоль
// [architect, junior, middle, senior, team lead]

Ngoại lệ

31. Ngoại lệ là gì?

Ngoại lệ là một vấn đề có thể xảy ra trong thời gian chạy. Đây là một tình huống đặc biệt phát sinh do một số lý do. Sơ đồ kế thừa ngoại lệ trông như thế này (bạn cần phải thuộc lòng ;)): 50 câu hỏi và câu trả lời phỏng vấn cốt lõi về Java hàng đầu.  Phần 2 - 3Sơ đồ cho thấy, nhìn chung, tất cả các ngoại lệ đều được chia thành hai nhóm - ngoại lệlỗi. Lỗi - JVM được sử dụng để hiển thị các lỗi mà sau đó ứng dụng không còn có ý nghĩa nữa. Ví dụ: StackOverFlowError, thông báo rằng ngăn xếp đã đầy và chương trình không thể chạy được nữa. Ngoại lệ - ngoại lệ được tạo theo chương trình trong mã. Có nhiều trường hợp ngoại lệ khác nhau, được chọn và không được kiểm tra, nhưng điều chính là chúng tồn tại, chúng có thể bị bắt và ứng dụng có thể tiếp tục hoạt động. Ngược lại, các ngoại lệ lại được chia thành các ngoại lệ kế thừa từ RuntimeException và các ngoại lệ khác của Ngoại lệ. Có đủ thông tin về vấn đề này. Chúng ta sẽ nói về những ngoại lệ được kiểm tra/không được kiểm tra bên dưới.

32. JVM xử lý các ngoại lệ như thế nào?

Làm thế nào nó hoạt động? Ngay khi một ngoại lệ được ném vào đâu đó, bộ thực thi sẽ tạo một Đối tượng ngoại lệ (ký hiệu là ExcObj). Nó lưu trữ tất cả thông tin cần thiết cho công việc - ngoại lệ được đưa ra và nơi xảy ra ngoại lệ. Việc tạo ExcObjvà truyền sang thời gian chạy không gì khác hơn là “ném một ngoại lệ”. ExcObjchứa các phương thức có thể được sử dụng để đến nơi ném ngoại lệ. Tập hợp các phương thức này được gọi là Call Stack. Tiếp theo, hệ thống thời gian chạy tìm kiếm một phương thức trong Ngăn xếp Cuộc gọi có thể xử lý ngoại lệ của chúng ta. Nếu nó tìm thấy một trình xử lý tương ứng, nghĩa là loại ngoại lệ khớp với loại trong trình xử lý thì mọi thứ đều ổn. Nếu không tìm thấy thì bộ thực thi sẽ chuyển mọi thứ tới trình xử lý ngoại lệ mặc định để chuẩn bị phản hồi và thoát. Nó trông như thế nào về mặt trực quan:
/**
* Пример, в котором показываются две опции — когда находится обработчик для исключения и когда нет.
*/
class ThrowerExceptionExample {

   public static void main(String[] args) throws IllegalAccessException {

       ThrowerExceptionExample example = new ThrowerExceptionExample();

       System.out.println(example.populateString());
   }

   /**
    * Здесь происходит перехват одного из возможных исключений — {@link IOException}.
    * А вот второй будет пробрасываться дальше вверх по вызову.
    */
   private String populateString() throws IllegalAccessException {
       try {
           return randomThrower();
       } catch (IOException e) {
           return "Caught IOException";
       }
   }

   /**
    * Здесь две опции: or бросается {@link IOException} or {@link IllegalAccessException}.
    * Выбирается случайным образом.
    */
   private String randomThrower() throws IOException, IllegalAccessException {
       if (new Random().nextBoolean()) {
           throw new IOException();
       } else {
           throw new IllegalAccessException();
       }
   }
}
Trong trường hợp của chúng tôi, CallStack sẽ có sơ đồ như sau:

randomThrower() => populateString() => main(String[] args)
Có hai lựa chọn: một hoặc ngoại lệ kia sẽ được ném ngẫu nhiên. Đối với IOException mọi thứ đều ổn, nếu nó được tạo ra thì kết quả của công việc sẽ là: "Caught IOException". Nhưng nếu có ngoại lệ thứ hai không có trình xử lý, chương trình sẽ dừng với kết quả đầu ra sau:

Exception in thread "main" java.lang.IllegalAccessException
  at ThrowerExceptionExample.randomThrower(CollectionExample.java:38)
  at ThrowerExceptionExample.populateString(CollectionExample.java:24)
  at ThrowerExceptionExample.main(CollectionExample.java:15)

33. Lập trình viên xử lý các trường hợp ngoại lệ như thế nào?

Trong các câu hỏi ở trên, chúng tôi đã sử dụng một số từ khóa nhất định để giải quyết các trường hợp ngoại lệ, bây giờ chúng tôi cần nói về chúng chi tiết hơn. Từ khóa là gì?
  • thử
  • nắm lấy
  • ném
  • ném
  • Cuối cùng
Điều quan trọng cần lưu ý là việc bắt, ném và ném chỉ có thể được sử dụng với java.lang.Throwable. Điều này sẽ không hoạt động với các loại khác. Bây giờ chúng ta sẽ thảo luận về thử, bắt và cuối cùng.
  • try-catch-finallylà một cấu trúc cho phép bạn bắt và xử lý một ngoại lệ một cách chính xác.
  • try- chỉ có thể có một lần, đó là lúc logic xảy ra;
  • catch— một khối nhận được một số loại ngoại lệ; có thể có nhiều ngoại lệ. Ví dụ: khối thử sẽ đưa ra một số ngoại lệ không liên quan gì đến nhau;
  • finally- “cuối cùng” khối này. Đây là khối sẽ được thực thi trong mọi trường hợp, bất kể điều gì được thực hiện trong thử, bắt.
Đây là những gì nó trông giống như:
try {
   // сюда передают тот code, который может вызвать исключение.
} catch (IOException e) {
   // первый catch блок, который принимает IOException и все его подтипы(потомки).
   // Например, нет file при чтении, выпадает FileNotFoundException, и мы уже соответствующе
   // обрабатываем это.
} catch (IllegalAccessException e) {
   // если нужно, можно добавить больше одного catch блока, в этом нет проблем.
} catch (OneException | TwoException e) {
   // можно даже объединять несколько в один блок
} catch (Throwable t) {
   // а можно сказать, что мы принимаем ВСЁ))))
} finally {
   // этот блок может быть, а может и не быть.
   // и он точно выполнится.
}
Đọc kỹ mô tả của ví dụ và mọi thứ sẽ rõ ràng)

34. ném và ném trong Java

ném

throwđược sử dụng khi bạn cần tạo một ngoại lệ mới một cách rõ ràng. Nó được sử dụng để tạo và ném các ngoại lệ tùy chỉnh. Ví dụ: các trường hợp ngoại lệ liên quan đến xác nhận. Thông thường, để xác thực, chúng kế thừa từ RuntimeException. Ví dụ:
// пример пробрасывания исключения
throw new RuntimeException("because I can :D");
Điều quan trọng là cấu trúc này chỉ có thể được sử dụng bởi thứ gì đó kế thừa từ Throwable. Đó là, bạn không thể nói điều này:
throw new String("How тебе такое, Илон Маск?");
Tiếp theo, công việc của luồng kết thúc và quá trình tìm kiếm bắt đầu tìm kiếm trình xử lý có thể xử lý nó. Khi không tìm thấy nó, nó sẽ chuyển sang phương thức đã gọi nó và do đó, quá trình tìm kiếm sẽ đi lên dòng lệnh gọi cho đến khi tìm thấy trình xử lý tương ứng hoặc để ứng dụng chạy. Hãy xem:
// Пример, который демонстрирует работу throw
class ThrowExample {

   void willThrow() throws IOException {
       throw new IOException("Because I Can!");
   }

   void doSomething() {
       System.out.println("Doing something");
       try {
           willThrow();
       } catch (IOException e) {
           System.out.println("IOException was successfully handled.");
       }
   }

   public static void main(String args[]) {
       ThrowExample throwExample = new ThrowExample();
       throwExample.doSomething();
   }
}
Nếu chạy chương trình, chúng ta nhận được kết quả như sau:

Doing something
IOException was successfully handled.

ném

throws- một cơ chế mà một phương thức có thể đưa ra một hoặc nhiều ngoại lệ. Chúng được thêm vào và phân tách bằng dấu phẩy. Hãy xem nó dễ dàng và đơn giản như thế nào:
private Object willThrow() throws RuntimeException, IOException, FileNotFoundException
Hơn nữa, điều quan trọng cần lưu ý là có thể có cả ngoại lệ được kiểm tra và không được kiểm tra. Tất nhiên, các trường hợp ngoại lệ không được kiểm tra có thể không được thêm vào throws, nhưng cách cư xử tốt lại nói khác. Nếu đây là những mục có thể kiểm tra được, thì bằng cách sử dụng phương pháp tạo ra chúng, bạn cần phải xử lý nó bằng cách nào đó. Có hai lựa chọn:
  1. Viết try-catchvới ngoại lệ kế thừa thích hợp và ở trên.
  2. Hãy sử dụng nó throwstheo cách tương tự để người khác đã gặp phải vấn đề này :D

35. Các ngoại lệ được kiểm tra và không được kiểm tra trong Java

Có hai loại ngoại lệ trong Java - được chọn và không được chọn.

Đã kiểm tra ngoại lệ:

Đây là những ngoại lệ được kiểm tra tại thời điểm biên dịch. Nếu một số mã trong một phương thức ném ra một ngoại lệ được kiểm tra trong một ngoại lệ, thì phương thức đó phải xử lý nó bằng cách sử dụng try-catchhoặc chuyển tiếp nó. Ví dụ: đọc một hình ảnh từ đường dẫn "/users/romankh3/image.png", sẽ cập nhật nó theo một cách nào đó (đối với chúng tôi điều này không quan trọng) và lưu lại.
class CheckedImageExample {
   public static void main(String[] args) {
       File imageFile = new File("/users/romankh3/image.png");
       BufferedImage image = ImageIO.read(imageFile);
       updateAndSaveImage(image, imageFile);
   }

   private static void updateAndSaveImage(BufferedImage image, File imageFile) {
       ImageIO.write(image, "png", imageFile);
   }
}
Mã như vậy sẽ không được biên dịch, vì các phương thức tĩnh ImageIO.read()đưa ra ImageIO.write()IOException, ngoại lệ này được kiểm tra và phải được xử lý tương ứng. Có hai tùy chọn ở đây mà chúng ta đã thảo luận ở trên: sử dụng try-catchhoặc chuyển tiếp thêm. Để hòa nhập tốt hơn, chúng ta sẽ làm điều này điều kia. Nghĩa là, updateAndSavechúng ta sẽ chuyển tiếp nó trong phương thức và sau đó sử dụng nó trong phương thức chính try-catch:
class CheckedImageExample {
   public static void main(String[] args) {
       File imageFile = new File("/users/romankh3/image.png");
       try {
           BufferedImage image = ImageIO.read(imageFile);
           updateAndSaveImage(image, imageFile);
       } catch (IOException e) {
           e.printStackTrace();
       }
   }

   private static void updateAndSaveImage(BufferedImage image, File imageFile) throws IOException {
       ImageIO.write(image, "png", imageFile);
   }
}

Các ngoại lệ không được kiểm tra:

Đây là những trường hợp ngoại lệ không được kiểm tra ở giai đoạn biên dịch. Nghĩa là, một phương thức có thể tạo ra RuntimeException, nhưng trình biên dịch sẽ không nhắc bạn xử lý nó bằng cách nào đó. Như được hiển thị bên dưới, chúng tôi có mọi thứ kế thừa từ RuntimeException và Lỗi đều được bỏ chọn. 50 câu hỏi và câu trả lời phỏng vấn cốt lõi về Java hàng đầu.  Phần 2 - 4Hãy xem xét chương trình Java sau đây. Mã biên dịch tốt nhưng đưa ra ngoại lệ khi chạy ArrayIndexOutOfBoundsException. Trình biên dịch cho phép nó biên dịch vì ArrayIndexOutOfBoundsExceptionđây là một ngoại lệ không được kiểm tra. Một tình huống phổ biến với một mảng, có thể là:
class CheckedImageExample {
   public static void main(String[] args) {
       int[] array = new int[3];
       array[5] = 12;
   }
}
Kết quả sẽ là:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
  at main(CheckedImageExample.java:12)
Nhân tiện, bạn có nhận thấy rằng trong Java không ai đặt tên ngắn không? Càng to càng tốt. Anh ấy, Spring Framework, đã rất thành công trong việc này: chỉ cần học một số lớp BeanFactoryPostProcessor )))

36. Tài nguyên dùng thử là gì?

Đây là một cơ chế mà tất cả các tài nguyên phải được đóng một cách chính xác. Không rõ bằng cách nào đó, phải không?) Trước hết, tài nguyên là gì... Tài nguyên là một đối tượng, sau khi làm việc với nó, bạn cần đóng nó lại, tức là gọi tệp close(). Tài nguyên là tất cả các đối tượng thực hiện một giao diện AutoClosable, từ đó thực hiện một giao diện Closeable. Điều quan trọng là chúng ta phải hiểu rằng mọi thứ đều InputStreamOutpuStreamtài nguyên và cần được phát hành một cách chính xác và thành công. Đây chính xác là lý do tại sao chúng ta cần sử dụng try-with-resourcecấu trúc. Đây là những gì nó trông giống như:
private void unzipFile(File zipFile) throws IOException {
   try(ZipInputStream zipOutputStream = new ZipInputStream(new FileInputStream(zipFile))) {
       ZipEntry zipEntry = zipOutputStream.getNextEntry();
       while (zipEntry != null) {

       }
   }
}

private void saveZipEntry(ZipEntry zipEntry) {
   // логика сохранения
}
Trong ví dụ này, tài nguyên là ZipInputStream, sau khi làm việc với nó, bạn sẽ cần đóng nó lại. Và để không phải nghĩ đến việc gọi phương thức close(), chúng ta chỉ cần xác định biến này trong khối thử, như trong ví dụ và trong khối này, chúng ta làm mọi thứ cần thiết. Ví dụ làm gì? Nó sẽ giải nén kho lưu trữ zip. Để làm điều này bạn cần sử dụng InputStream'om. Bạn có thể xác định nhiều biến; chúng được phân tách bằng dấu chấm phẩy. Vấn đề là gì? Nhưng bạn có thể sử dụng finallymột khối, bạn có thể nói. Đây là một bài viết trình bày chi tiết các vấn đề với phương pháp này. Nó cũng mô tả toàn bộ danh sách các lỗi có thể xảy ra với người không sử dụng thiết kế này. Tôi khuyên bạn nên đọc nó;) Ở phần cuối cùng có các câu hỏi/câu trả lời về chủ đề Đa luồng. Hồ sơ GitHub của tôi
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION