Java 11

Nam Vu
6 min readOct 17, 2019

Sau Java 8, Oracle sẽ liên tục phát triển và ra version mới sau mỗi 6 tháng, hiện tại tại thời điểm bài viết này (10–2019) phiên bản mới nhất là Java 13. Điều này sẽ gây chút bối rối với những Java Developer vốn quen với sự "ổn định", nhưng thực tế thì chỉ sau 3 năm mới có một phiên bản LTS (long term support), các phiên bản khác chỉ là các phiên bản thử nghiệm và sẽ bị thay thế bởi các phiên bản khác mới hơn.

https://adoptopenjdk.net/support.html

Roadmap bên trên ta có thể thấy Java 11 là bản LTS mới nhất và sẽ được support và maintenance đến tháng 9 năm 2022, và Java 8 sẽ được hỗ trợ cho tới tháng 9 năm 2023. Và theo dự kiến thì một bản LTS gần nhất sẽ là Java 15, cho nên nếu bạn có một dự án mới hoặc có kế hoạch nâng cấp phiên bản Java thì Java 11 là lựa chọn tốt ở thời điểm này.

Tuy nhiên thì từ khi Java về tay Oracle thì "cái gì cũng có cái giá" của nó, có nghĩa là nếu bạn dùng JDK dành cho các phiên bản thương mại hóa, bạn phải trả tiền cho Oracle. Còn nếu muốn dùng free cho các phiên bản thương mại thì bạn có thể lựa chọn OpenJDK nhưng phải tự cập nhật mới mỗi 6 tháng.

Những điểm đáng chú ý của Java 11 đó là cải tiến về mặt ngôn ngữ giúp viết code "tự nhiên hơn" có nghĩ là dễ đọc dễ hiểu cho LTV hơn.

Java 11 phát triển một project JShell là một công cụ REPL trong Java, giúp LTV có thể thử nghiệm nhanh những đoạn code hoặc vài demo nhỏ.

Tiếp theo là project Jigsaw thay đổi cách ứng dụng Java đóng gói và cung cấp tiện ích để đóng gói JRE vào ứng dụng Java giúp ứng dụng có thể chạy trên từng nền tảng OS mà không cần cài đặt JRE hay bất kỳ một thư viện nào khác, cũng có thể hình dùng Jigsaw giống một bản mini Docker cho ứng dụng chạy Java vậy.

JVM 11 cung cấp một bộ Garbage Collector mới có tên là Epsilon ở phiên bản 318 và ZGC với phiên bản mới nhất là 333, ở một bài viết khác người viết sẽ đề cập tới bộ GC mới này. Và còn thêm nhiều tính năng nữa là tích hợp HTTP Client vào JDK hay bỏ bộ (deprecate) J2EE ra khỏi JDK...

Ở nội dung bài viết này, người viết sẽ đề cập với những cải tiến về mặt ngôn ngữ (language) của Java 11.

1. VAR

Chắc hẳn tất cả mọi người đều biết tới JavaScript và rất quen thuộc với biến kiểu var , đây là một kiểu Local Variable Type Definition được giới thiệu lần đầu tiên ở phiên bản Java 10, giúp LTV có thể khai báo biến mà không cần chỉ rõ kiểu dữ liệu của nó.

Ví dụ thay vì phải mô tả rõ kiểu dữ liệu kiểu như int a, String b, float c, boolean d, List<Person> e ... thì ta chỉ cần đơn giản viết là var a, var b, var c ...

Cách viết cũ cần khai báo kiểu dữ liệu:

Viết lại bằng cách sử dụng var:

Cách viết này rất gọn gàng dễ đọc, tuy nhiên một vài LTV không thích điều này vì đã quen với việc khai báo rõ ràng kiểu dữ liệu. Nhưng đôi khi việc khai báo này rất dài dòng và không cần thiết vì đôi lúc chúng ta không cần quan tâm với kiểu dữ liệu như ví dụ bên dưới khi ta cần lặp một Map như sau:

Những kiểu dữ liệu như Iterator<? extends Map.Entry<? extends String, ? extends Number>> hay Map.Entry<? extends String, ? extends Number> nó quá dài dòng và trong trường hợp này ta cũng chẳng cần quan tâm kiểu dữ liệu nó là gì. Ta có thể viết lại băng cách dùng var như sau:

Nhìn nó gọn gàng dễ đọc dễ hiểu hơn (human readable) đúng không :D.

Một vài chú ý khi dùng var đó là, var chỉ sử dụng trong biến nội bộ (local) một method và không được dùng làm biến đầu vào của method hay làm biến toàn cục (instance) hoặc properties của một class.

Tuy nhiên var không phải là một "magic keyword" mà ta có thể đặt nó lung tung, mục đích của var là dễ đọc dễ hiểu (human readable), một vài trường hợp nếu sử dụng thì người đọc sẽ khó có thể xác định được kiểu dữ liệu của biến thì không nên sử dụng ví dụ như:

Đoạn code trên nếu đọc thì thấy nó chẳng có ý nghĩa gì cả, người đọc sẽ không thể nhìn thấy ngay được kiểu dữ liệu của tmp là gì, vì vậy việc sử dụng var như bên trên đã phản tính human readable. Tốt nhất ta nên viết lại bằng cách khai báo biến rõ ràng lại như sau:

2. Collections

Những cải tiến trong Java 11 mục đích chính là giúp việc viết và đọc code dễ hiểu hơn, và ngoài biến var thì Java 11 cũng cung cấp một vài method giúp cho việc thao tác với Collections dễ dàng hơn, hãy cùng tìm hiểu nó thông qua một ví dụ khi ta cần khai báo một unmodifiableList (một List không thể thay đổi hay thêm mới elements) trong Java 8 ta sẽ khai báo như sau:

Trong Java 11 việc khai báo này đơn giản là dùngList.of() như sau:

Tương tự ta có thể làm điều này với HashMap hoặc HashSet

Java 8:

Java 11 với Set.ofMap.entry :

Hoặc nếu Map có dưới 10 phần tử thì ta có thể dùng Map.of() và dữ liệu trong Map sẽ có kiểu Key-Value.

Super easy and super convenience :D

3. Stream

Stream ra mắt từ phiên bản Java 8 và có thể nói là một cuộc cách mạng và thay đổi hoàn toàn cách tư duy cũng như phong cách lập trình mà các lập trình viên Java lâu năm vẫn áp dụng. Java 11 cũng bổ xung thêm vài tính năng nhỏ như stream giờ có thể collect() unmodifiable lists, sets, etc ... Ví dụ:

Ngoài ra Stream được bổ sung thêm hai method là takeWhile()dropWhile().

takeWhile() : Dùng để chỉ cho phép Stream tiếp tục thực hiện khi thỏa mãn điều kiện (condition) khai báo trong nó.

dropWhile(): Ngược lại với takeWhile() thì nó dùng để điều khiển Stream bỏ qua việc thực thi khi thỏa mãn điều kiện (condition) trên trong nó.

Ví dụ:

takeWhile()
dropWhile()

Thêm một cải tiến nữa của Stream là cung cấp Prediction.not() để kiểm tra một condition nào đó không thỏa mãn, ví dụ ta muốn Stream<String> ta muốn lọc (filter) ra một List<String> không có giá trị rỗng, theo cách thông thường ta dùng hàm filter() và dùng toán tử ! để filter ví dụ.

Bản thân tôi thì không thích dùng toán tử !, vì nó rất khó nhìn dễ nhầm lẫn, với Java 11 ta có thể dùng Prediction.not() để thay thế ví dụ:

Code sáng sủa và dễ đọc hơn rất nhiều đúng không :D ?

4. Optional

Optional xuất hiện từ Java 8, giúp cho việc LTV "deal with" nỗi ác mộng NullPointerException dễ dàng hơn. Và như chúng ta đã biết khi gặp một biến Optional thì để lấy dữ liệu ra chúng ta phải check rằng value có khác Null không bằng cách gọi hàm isPresent() như ví dụ:

Để giảm việc sử dụng if else trong trường hợp này Java 11 cung cấp thêm một phương thức là ifPresentOrElse() với 2 tham số Lamda, như ví dụ trên ta có thể viết lại ví dụ bên trên như sau:

Hoặc dùng phương thức or() trong Optional để trả về một kết quả khác nếu Optional không có giá trị hoặc Throw ra NoSuchElementException và cũng có thể sử dụng Optional trong Stream như ví dụ dưới sau đây:

Và cuối cùng là Java 11 cung cấp thêm một method nữa Optional.isPresent() bên cạnh Optional.isEmpty() có ý nghĩa ngược lại với isEmpty() là nếu Optional có dữ liệu thì..

Những cải tiến thêm trong Optional khiến việc viết code trong sáng dễ, và giúp cho việc đọc hiểu và bảo trì (maintenance) code, điều này cho thấy những cải tiến trong Java 11 trú trọng và vào việc cải tiến ngôn ngữ trong sáng và dễ hiểu để bắt kịp với những ngôn ngữ mới ra sau như C# hay Go.

HẾT!

--

--