Mặc dù theo dự kiến đến tháng 3/2019 JDK phiên bản 12 mới được tung ra, nhưng thời gian này nhà phát hành đã cập nhật 1 số đề xuất nâng cấp cho phiên bản JDK 12. Trong bài này mình sẽ nói đến 1 số điểm nổi bật mà có thể sẽ xuất hiện trong JDK 12 chính thức.
Tuy chưa phát hành bản chính thức và kể cả Beta, nhưng nhà phát hành đã cho phép chúng ta trải nghiệm trước 1 bản có tên là JDK 12 EAB (Early-Access Build). Các bạn có thể tải về tại địa chỉ: https://jdk.java.net/12/
Làm thế nào để sử dụng JDK 12?
Vì đây không phải là bản chính thức nên việc tích hợp nó vào các IDE có thể sẽ không được chấp nhận, vậy nên hãy dùng command-line để trải nghiệm các feature của nó.
- B1: Download JDK 12 phù hợp với hệ điều hành của bạn
- B2: Giải nén gói tải về
- B3: Thực hiện biên dịch file mã nguồn java bằng lệnh kèm tham số
--enable-preview -source 12
jdk-12\bin\javac --enable-preview -source 12 test.java
- B4: Thực hiện chạy file class đã biên dịch bằng lệnh kèm tham số
--enable-preview
jdk-12\bin\java --enable-preview test
Hoặc, nếu bạn đang sử dụng IntelliJ IDE thì có thể cập nhật lên bản 2018.3. Ở phiên bản này IntelliJ đã hỗ trợ tích hợp JDK 12 Preview và cho phép các syntax mới của JDK 12
JDK 12 có gì mới?
Như ảnh trên, ta thấy luôn 2 tính năng mới nổi bật nhất của JDK 12 là Switch Expressions, Raw String Literals được mô tả trong JEP (JDK Enhancement Proposals) 325 và JEP 326
1. JEP 325: Switch Expressions
JEP này mô tả về cách sử dụng biểu thức switch mới, giảm thiểu rủi ro khi run-time. Thử so sánh cách viết hiện tại và cách viết mới
Hiện tại:
switch (day) { case MONDAY: case FRIDAY: case SUNDAY: System.out.println(6); break; case TUESDAY: System.out.println(7); break; case THURSDAY: case SATURDAY: System.out.println(8); break; case WEDNESDAY: System.out.println(9); break; }
Mới:
switch (day) { case MONDAY, FRIDAY, SUNDAY -> System.out.println(6); case TUESDAY -> System.out.println(7); case THURSDAY, SATURDAY -> System.out.println(8); case WEDNESDAY -> System.out.println(9); }
Ở đây ta có thể thấy 1 số điểm lợi như sau
- Code ngắn hơn nhiều và dễ nhìn hơn
- Không cần sử dụng break tại mỗi case. Lỗi thiếu break là lỗi rất hay gặp ở những người mới làm quen
Trong quá trình code, đâu đấy các bạn cũng đã từng có lúc phải xử lý các đoạn tương tự như dưới đây
int quarter; switch (month) { case JAN: case FEB: case MAR: quarter = 1; break; case APR: case MAY: case JUN: quarter = 2; break; case JUL: .............. }
Để lấy được 1 giá trị tương ứng với các case thì phải sử dụng 1 biến cục bộ rồi lần lượt gán lại giá trị trong từng case
Nhưng với JDK 12 thì việc này đã đơn giản hơn rất nhiều vì switch bây giờ có thể trả về 1 giá trị giống như 1 function bình thường
int quarter = switch (month) { case JAN, FEB, MAR -> 1; case APR, MAY, JUN -> 2; case JUL, AUG, SEP -> 3; case OCT, NOV, DEC -> 4; };
Hoặc ngoài việc trả về 1 giá trị, bạn muốn xử lý thêm công việc gì đó trong case thì có thể trả giá trị cho switch với break
int quarter = switch (month) { case JAN, FEB, MAR -> { System.out.println("Quarter I"); break 1; } case APR, MAY, JUN -> { System.out.println("Quarter II"); break 2; } case JUL, AUG, SEP -> { System.out.println("Quarter III"); break 3; } case OCT, NOV, DEC -> { System.out.println("Quarter IV"); break 4; } };
2. JEP 326: Raw String Literals
Ở JEP này mình thấy khá hữu ích cho tầng thao tác CSDL trong project, nơi mà thường xuyên phải viết những câu lệnh SQL dài dằng dặc trong code, hoặc những đoạn sinh mã HTML từ controller, một ví dụ ngắn về sql như dưới
String sql = "" + " select sv.Masv, Tensv\n" + " from Sinhvien sv, Ketqua kq\n" + " where sv.Masv = kq.Masv and Diem < 5 and Lop = 'L04'\n" + " group by sv.Masv, Tensv\n" + " having COUNT(Diem) > 2";
Từ trước đến giờ mình vẫn thấy khá rối mắt với những kiểu viết SQL trong code như này, vừa không đúng chuẩn lại ảnh hưởng đến hiệu năng vì cộng chuỗi liên tục. Mà nếu sử dụng append() thì tốn công code. Rồi cả khi fix lỗi cần test câu sql trên tool sql nào đó thì phải copy từ code vào tool rồi xóa mấy ký tự thừa thãi kia thấy thật phiền phức.
Nhưng với JDK 12 thì việc này đã được giải quyết khá tốt bằng cách sử dụng Raw String Literals. Thay vì sử dụng dấu nháy kép (“) thì ta có thể sử dụng dấu (`) để bao 1 đoạn string nhiều dòng, có thể chứa cả các ký tự đặc biệt trong đó như nháy kép nháy đơn mà không cần thêm ký tự chéo () đằng trước. Tóm lại với Raw String Literal thì bất kể gõ ký tự gì trong đó nó đều chấp nhận hết, ta vẫn có thể giữ được chuỗi nguyên bản.
String sql = ` select sv.Masv, Tensv from Sinhvien sv, Ketqua kq where sv.Masv = kq.Masv and Diem < 5 and Lop = 'L04' group by sv.Masv, Tensv having COUNT(Diem) > 2`; System.out.println(sql);
Thử print ra màn hình để xem kết quả
select sv.Masv, Tensv from Sinhvien sv, Ketqua kq where sv.Masv = kq.Masv and Diem < 5 and Lop = 'L04' group by sv.Masv, Tensv having COUNT(Diem) > 2
Hiện trạng văn bản được giữ nguyên, nhưng nó lại giữ nguyên cả 1 loạt khoảng trống ở đầu dòng. Thế nên cùng với Raw String Literals thì JDK 12 cũng cung cấp thêm 1 số method căn chỉnh lại cái này, bằng cách thêm align() khi print System.out.println(sql.align())
select sv.Masv, Tensv from Sinhvien sv, Ketqua kq where sv.Masv = kq.Masv and Diem < 5 and Lop = 'L04' group by sv.Masv, Tensv having COUNT(Diem) > 2
Vậy muốn viết chính ký tự (`) trong chuỗi thì làm thế nào? Đơn giản chỉ cần dùng 2 ký tự (``) để bao chuỗi thay vì 1.
String sql = `` select sv.`Masv`, `Tensv` from Sinhvien sv, Ketqua kq where sv.Masv = kq.Masv and Diem < 5 and Lop = 'L04' group by sv.Masv, Tensv having COUNT(Diem) > 2``; System.out.println(sql);
Nhưng mình nghĩ nên hạn chế dùng 2 dấu (``) vì trường hợp này nó sẽ phân tách từng ký tự trong chuỗi để xử lý kiểu như array chứ không còn là 1 string liên tục. Các bạn có thể xem chi tiết hơn tại http://openjdk.java.net/jeps/326
Ngoài ra, có 1 số JEP khác của JDK 12 như
3. JEP 189: Shenandoah: A Low-Pause-Time Garbage Collector (Experimental)
JEP này mô tả về việc cập nhật thuật toán mới cho GC, giúp cho việc xử lý rác trên GC nhanh hơn và tối ưu hơn. Sẽ có 1 thời gian cố định cho các lần xử lý rác.
4. JEP 334: JVM Constants API
Cái này theo mình hiểu là sẽ có 1 constant pool lưu trữ các bản mô tả của class và method, mục đích để tối ưu tốc độ của các thao tác gọi class và method khi run-time
5. JEP 344: Abortable Mixed Collections for G1
Tiếp của JEP 189, nếu thời gian xử lý rác vượt quá mục tiêu cho phép thì nó sẽ bị hủy, tránh việc ảnh hướng đến hệ thống.
6. JEP 346: Promptly Return Unused Committed Memory from G1
Release sớm các vùng nhớ ít sử dụng một cách hợp lý. Cái này sẽ đánh giá các vùng nhớ có tần xuất sử dụng quá thấp hoặc có khả năng ko sử dụng đến để giải phóng trả lại cho heap.
7. JEP 230: Microbenchmark Suite
Tích hợp sẵn một bộ Microbenchmark vào JDK để kiểm tra hiệu năng của JDK
8. JEP 340: One AArch64 Port, Not Two
Nhà phát hành loại bỏ các bộ source liên quan đến arm64 port (hotspot/cpu/arm), chỉ giữ lại aarch64 port (hotspot/cpu/aarch64) để giảm thiểu việc trùng lặp code trong JDK, các xử lý đặc thù trên 2 port khác nhau sẽ được phân tách bằng điều kiện #ifdefs
9. JEP 341: Default CDS Archives
Tính năng chia sẻ dữ liệu lớp (CDS) đã xuất hiện từ JDK 8u40 nhằm mục đích tăng tốc độ khởi động, sử dụng chung bộ nhớ. Các lớp dữ liệu được chia sẻ sẽ lưu trong thư mục lib/server. Nhưng cái này chỉ xuất hiện nếu như chạy chương trình với tham số -Xshare:dump
. Việc này làm cho phần lớn lập trình viên đều không biết tới nó.
Trong JEP này mô tả, nó sẽ được chạy tự động theo JVM để sẵn sàng sử dụng. Nếu muốn tắt nó hãy sử dụng tham số -Xshare:off
để vô hiệu hóa CDS
Tham khảo mô tả chi tiết các JEP của JDK 12 tại đây: http://openjdk.java.net/projects/jdk/12/
mới từ 7->8 đã thấy nhiều thứ thay đổi quá rồi mà đại ca cho phát giới thiệu Java 12 =)))))))))))
7->11 tràn lan bài tiếng việt trên mạng rồi, viết làm gì nữa 😀