Mục lục
- 1 Modular System – Jigsaw Project
- 2 Java 9 REPL (JShell)
- 3 Factory Method cho Immutable List, Set, Map và Map.Entry
- 4 Private method trong interface
- 5 Process AP
- 6 Reactive Streams
- 7 Diamond Operator - Anonymous Inner Class
- 8 Cải tiến Stream API
- 9 Cải tiến @Deprecated annotation
- 10 New HTTP Client
- 11 Optional Stream
Java 9 được giới thiệu với rất nhiều tính năng mới mà có lẽ các Java dev của chúng ta phải sẵn sàng để cập nhật các kiến thức mới để trong tương lại phát triển các ứng dụng trở nên tốt hơn.
Trong bài viết này, chúng ta sẽ cùng nhau điểm qua một số tính năng nổi bật trong Java 9 để có cái nhìn tổng quan về phiên bản mới của Java lần này. Ngoài ra, các bạn có thể xem danh sách đầy đủ các chức năng tại trang web chính thức của openjdk.
Modular System – Jigsaw Project
Một trong số những thay đổi lớn của Java 9 đó là Module System. Oracle Corp đã giới thiệu các tính năng mới về phần này, như một phần của dự án Jigsaw Project.
- Modular JDK
- Modular Java Source Code
- Modular Run-time Images
- Encapsulate Java Internal APIs
- Java Platform Module System
Các phiên bản từ trước Java 9 sử dụng đang sử dụng kiến trúc Monolithic Jars (Nguyên khối) để phát triển các ứng dụng. Kiến trúc này có rất nhiều hạn chế và nhược điểm. Để tránh tất cả những thiếu sót này, Java SE 9 ra mắt với Module System nhầm khắc phục những nhược điểm này.
JDK 9 sắp ra mắt với 92 module (có thể thay đổi trong bản phát hành cuối cùng). Chúng ta có thể sử dụng các JDK Module và cũng có thể tự tạo các module riêng cho mình.
module com.java9.deft { }
Ở đây chúng ta đang sử dụng từ khoá module để khởi tạo một module đơn giản. Trong đó, mỗi module phải có tên, mã nguồn và các tài nguyên khác.
Java 9 REPL (JShell)
Oracle Corp đã giới thiệu một công cụ mới có tên gọi là jshell. Nó là viết tắt của Java Shell và còn được gọi là REPL (Read Evaluate Print Loop).Nó được sử dụng để thực thi và kiểm tra bất kỳ cấu trúc Java nào như class, interface, enum, objec, syntax vv. rất dễ dàng
Chúng ta có thể tải xuống phần mềm JDK 9 EA (Early Access) từ https://jdk9.java.net/download/
G:\>jshell | Welcome to JShell -- Version 9-ea | For an introduction type: /help intro jshell> int a = 10 a ==> 10 jshell> System.out.println("a value = " + a ) a value = 10
Factory Method cho Immutable List, Set, Map và Map.Entry
Java 9 cung cấp một số factory method dùng để khởi tại các List, Set, Map và Map.entry object cách nhanh chóng và tiện lợi.
Trong Java SE 8 và các phiên bản trước đó, Chúng ta có thể sử dụng các phương thức tiện ích của Collections như unmodifiableXXX để tạo các đối tượng Immutable Collection. Ví dụ, nếu chúng ta muốn tạo một Immutable List thì chúng ta có thể sử dụng phương thức Collections.unmodifiableList.
Tuy nhiên, các phương thức Collections.unmodifiableXXX này là có vẽ tẻ nhạt và dài dòng. Để khắc phục những thiếu sót đó, Java 9 đã thêm một số phương thức tiện ích vào các interface List, Set và Map cho phép khởi tạo các Immutable collection tiện lợi hơn thông qua of() method.
Ví dụ tạo Immutable List
List immutableList = List.of("one","two","three");
Immutable Map
Map.of(1, "one", 2, "two", 3, "three")
Private method trong interface
Trong Java 9, chúng ta có thể triển khai mã code thực thi bên trong một method của interface thông qua Default và Static method. Tuy nhiên chúng ta vẫn không thể tạo một private method trong interface.
Kể từ Java 9, chúng ta có thể tạo các private method trong interface, kể cả private static method.
public interface Card{ private Long createCardID(){ // Method implementation goes here. } private static void displayCardDetails(){ // Method implementation goes here. } }
Process AP
Process API đã được cải tiến để kiểm soát và quản lý các quy trình của hệ điều hành.
Process Information
Lớp java.lang.ProcessHandle chứa hầu hết các chức năng mới:
ProcessHandle self = ProcessHandle.current(); long PID = self.getPid(); ProcessHandle.Info procInfo = self.info(); Optional<String[]> args = procInfo.arguments(); Optional<String> cmd = procInfo.commandLine(); Optional<Instant> startTime = procInfo.startInstant(); Optional<Duration> cpuUsage = procInfo.totalCpuDuration();
ProcessHandle.current() trả về một obejct đại diện cho một process hiện tại đang chạy trong JVM. Infor subclass cung cấp các thông tin chi tiết của process.
Destroying Processes
Giả sử mình có đoạn mã code sau dùng để dừng tồn bộ các process con đang chạy của một process với destroy() method.
childProc = ProcessHandle.current().children(); childProc.forEach(procHandle -> { assertTrue("Could not kill process " + procHandle.getPid(), procHandle.destroy()); });
Try With Resources Improvement
Java SE 7 đã giới thiệu một cấu trúc xử lý ngoại lệ mới: Try-With-Resources giúp quản lý các tài nguyên một cách tự động. Tuy nhiên các biến phải được khai báo bên trong mệnh đề để được quản lý.
Trong Java 9 có một sự cải tiến bổ sung,nếu tài nguyên được tham chiếu ở lần sau cuối hoặc là final variable câu lệnh try-with-resources có thể quản lý tài nguyên mà không cần khai báo biến mới.
Java 7 example
void testARM_Before_Java9() throws IOException{ BufferedReader reader1 = new BufferedReader(new FileReader("deft.txt")); try (BufferedReader reader2 = reader1) { System.out.println(reader2.readLine()); } }
Java 9 Example
void testARM_Java9() throws IOException{ BufferedReader reader1 = new BufferedReader(new FileReader("deft.txt")); try (reader1) { System.out.println(reader1.readLine()); } }
Reactive Streams
Ngày nay, Reactive Programming trở nên vô cùng phổ biến trong phát triển các ứng dụng với một số lợi ích tuyệt vời mà nó mang lại. Scala, Play, Akka, etc. Framework cũng đã tích hợp Reactive Streams và thu về một số lợi ích nhất định.
Java 9 cũng đã mang Reactive Streams API vào mình. Nó là một Publish/Subscribe famework để phát triển các ứng dụng Asynchronous, Scalable and Parallel một cách dễ dàng với ngôn ngữ Java.
Java 9 đã giới thiệu API sau để triển khai Reactive Streams trong các ứng dụng Java:
- java.util.concurrent.Flow
- java.util.concurrent.Flow.Publisher
- java.util.concurrent.Flow.Subscriber
- java.util.concurrent.Flow.Processor
Diamond Operator - Anonymous Inner Class
SE 7 đã giới thiệu một tính năng mới: Diamond Operator để tránh mã thừa, nhằm cải thiện khả năng đọc. Tuy nhiên, trong Java SE 8, Oracle Corp (Nhà phát triển thư viện Java) đã phát hiện ra rằng một số hạn chế trong việc sử dụng Diamond Operator với Anonymous Inner Class. Java 9 đã cải thiện vấn đề này.
FooClass<Integer> fc = new FooClass<>(1) { // anonymous inner class }; FooClass<? extends Integer> fc0 = new FooClass<>(1) { // anonymous inner class }; FooClass<?> fc1 = new FooClass<>(1) { // anonymous inner class };
Cải tiến Stream API
Stream API có lẽ là một trong những tính năng khiến cho cú pháp và mã nguồn Java trở nên mạnh mẽ, ngắn gọn và dễ đọc. Trong phiên bản Java 9 lần này, giới thiệu 4 method mới trong java.util.Stream interface. Trong đó có 2 method quan trọng là dropWhile và takeWhile.
Method takeWhile() sẽ nhận một predicate làm tham số và trả về một Stream của các phần tử con thoả điều kiện predicate đặt ra.
Stream.of(1,2,3,4,5,6,7,8,9,10).takeWhile(i -> i < 5 ) .forEach(System.out::println); 1 2 3 4
Cải tiến @Deprecated annotation
Trong Java SE 8 và các phiên bản trước đó, @Deprecated annotation chỉ là một Marker interface mà không có bất kỳ phương thức nào. Nó được sử dụng để đánh dấu một API Java là một class, field, method, interface, constructor, enum, v.v.
Java 9 đã cải tiến đã cải tiến nhầm cung cấp nhiều thông tin hơn về các deprecated API (Các API sắp không được dùng) và cũng cung cấp một công cụ để phân tích các deprecated API được sử dụng trong ứng dụng. Chúng ta có thêm 2 method cho deprecated interface là forRemoval và since nhầm bổ sung thêm thông tin.
New HTTP Client
Một sự thay thế đã được chờ đợi từ lâu của HttpURLConnection cũ. API mới nằm trong java.net.http package.
Nó hỗ trợ cả HTTP / 2 protocol và WebSocket, có hiệu suất tương đương với Apache HttpClient, Netty và Jetty.
HttpRequest request = HttpRequest.newBuilder() .uri(new URI("https://postman-echo.com/get")) .GET() .build(); HttpResponse<String> response = HttpClient.newHttpClient() .send(request, HttpResponse.BodyHandler.asString());
Optional Stream
java.util.Optional.stream () cung cấp cho chúng ta một cách dễ dàng để sử dụng sức mạnh của Stream trên các Optional object. chọn:
List<String> filteredList = listOfOptionals.stream() .flatMap(Optional::stream) .collect(Collectors.toList());