點贊再看,養成好習慣java
JAVA 這幾年的更新實在是太太太……快了,JAVA 8 都還沒用多久,16 都已經發布了。自從 JAVA 8 發佈了 Lambda 和 Stream 以後,JAVA 就像打了雞血同樣,半年一個版本的發佈,生產隊的驢也沒這麼勤快。 json
致使咱們如今徹底跟不上 JAVA 發佈的節奏,我司目前還停留在 JAVA 8,甚至部分老系統還在使用 JAVA 7,根本不能輕易的升級。 安全
不過雖然暫時用不上最新版本的 JAVA,但瞭解每一個新版本的主要特性仍是很重要的,否則哪天真跟着升級了,那還不得一臉懵逼。 bash
本文就帶你快速瞭解 JAVA 9 - 16 的主要新特性,早學完早下班!markdown
JAVA 8 對接口增長了默認方法的支持,在 JAVA 9 中對該功能又來了一次升級,如今能夠在接口裏定義私有方法,而後在默認方法裏調用接口的私有方法。 app
這樣一來,既能夠重用私有方法裏的代碼,又能夠不公開代碼ide
public interface TestInterface {
default void wrapMethod(){
innerMethod();
}
private void innerMethod(){
System.out.println("");
}
}
複製代碼
JAVA 5 就引入了泛型(generic),到了 JAVA 7 開始支持鑽石(diamond)運算符:<>
,能夠自動推斷泛型的類型:函數
List<Integer> numbers = new ArrayList<>();
複製代碼
可是這個自動推斷類型的鑽石運算符可不支持匿名內部類,在 JAVA 9 中也對匿名內部類作了支持:工具
List<Integer> numbers = new ArrayList<>() {
...
}
複製代碼
try-with-resources
JAVA 7 中增長了try-with-resources
的支持,能夠自動關閉資源:post
try (BufferedReader bufferReader = new BufferedReader(...)) {
return bufferReader.readLine();
}
複製代碼
但須要聲明多個資源變量時,代碼看着就有點噁心了,須要在 try 中寫多個變量的建立過程:
try (BufferedReader bufferReader0 = new BufferedReader(...);
BufferedReader bufferReader1 = new BufferedReader(...)) {
return bufferReader0.readLine();
}
複製代碼
JAVA 9 中對這個功能進行了加強,能夠引用 try 代碼塊以外的變量來自動關閉:
BufferedReader bufferReader0 = new BufferedReader(...);
BufferedReader bufferReader1 = new BufferedReader(...);
try (bufferReader0; bufferReader1) {
System.out.println(br1.readLine() + br2.readLine());
}
複製代碼
JAVA 10 帶來了一個頗有意思的語法 - var
,它能夠自動推斷局部變量的類型,之後不再用寫類型了,也不用靠 lombok 的 var
註解加強了
var message = "Hello, Java 10";
複製代碼
不過這個只是語法糖,編譯後變量仍是有類型的,使用時仍是考慮下可維護性的問題,否則寫多了可就成 JavaScript 風格了
JAVA 11 中對 Lambda 語法也支持了 var
這個自動類型推斷的變量,經過 var 變量還能夠增長額外的註解:
List<String> languages = Arrays.asList("Java", "Groovy");
String language = sampleList.stream()
.map((@Nonnull var x) -> x.toUpperCase())
.collect(Collectors.joining(", "));
assertThat(language).isEqualTo("Java, Groovy");
複製代碼
之前編譯一個 java 文件時,須要先 javac 編譯爲 class,而後再用 java 執行,如今能夠一把梭了:
$ java HelloWorld.java
Hello Java 11!
複製代碼
Java Flight Recorder 是個灰常好用的調試診斷工具,不過以前是在 Oracle JDK 中,也跟着 JDK 11 開源了,OpenJDK 這下也能夠用這個功能,真香!
在以前的 JAVA 版本中,switch
語法仍是比較囉嗦的,若是多個值走一個邏輯須要寫多個 case
:
DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek();
String typeOfDay = "";
switch (dayOfWeek) {
case MONDAY:
case TUESDAY:
case WEDNESDAY:
case THURSDAY:
case FRIDAY:
typeOfDay = "Working Day";
break;
case SATURDAY:
case SUNDAY:
typeOfDay = "Day Off";
}
複製代碼
到了 JAVA 12,這個事情就變得很簡單了,幾行搞定,並且!還支持返回值:
typeOfDay = switch (dayOfWeek) {
case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> "Working Day";
case SATURDAY, SUNDAY -> "Day Off";
};
複製代碼
以前處理動態類型碰上要強轉時,須要先 instanceof
判斷一下,而後再強轉爲該類型處理:
Object obj = "Hello Java 12!";
if (obj instanceof String) {
String s = (String) obj;
int length = s.length();
}
複製代碼
如今 instanceof
支持直接類型轉換了,不須要再來一次額外的強轉:
Object obj = "Hello Java 12!";
if (obj instanceof String str) {
int length = str.length();
}
複製代碼
JAVA 12 中雖然加強了 swtich
語法,但並不能在 ->
以後寫複雜的邏輯,JAVA 12 帶來了 swtich
更完美的體驗,就像 lambda
同樣,能夠寫邏輯,而後再返回:
typeOfDay = switch (dayOfWeek) {
case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> {
// do sth...
yield "Working Day";
}
case SATURDAY, SUNDAY -> "Day Off";
};
複製代碼
你是否還在爲大段帶換行符的字符串報文所困擾,換行吧一堆換行符,不換行吧看着又難受:
String json = "{\"id\":\"1697301681936888\",\"nickname\":\"空無\",\"homepage\":\"https://juejin.cn/user/1697301681936888\"}";
複製代碼
JAVA 13 中幫你解決了這個噁心的問題,增長了文本塊的支持,如今能夠開心的換行拼字符串了,就像用模板同樣:
String json = """ { "id":"1697301681936888", "nickname":"空無", "homepage":"https://juejin.cn/user/1697301681936888"
}
"""; 複製代碼
通常咱們建立一個 POJO 類,須要定義屬性列表,構造函數,getter/setter,比較麻煩。JAVA 14 爲咱們帶來了一個便捷的建立類的方式 - record
public record UserDTO(String id,String nickname,String homepage) { };
public static void main( String[] args ){
UserDTO user = new UserDTO("1697301681936888","空無","https://juejin.cn/user/1697301681936888");
System.out.println(user.id);
System.out.println(user.nickname);
System.out.println(user.id);
}
複製代碼
IDEA 也早已支持了這個功能,建立類的時候直接就能夠選: 不過這個只是一個語法糖,編譯後仍是一個 Class,和普通的 Class 區別不大
NullPointerException 算是 JAVA 裏最多見的一個異常了,但這玩意提示實在不友好,遇到一些長一點的鏈式表達式時,沒辦法分辨究竟是哪一個對象爲空。
好比下面這個例子中,究竟是 innerMap
爲空呢,仍是 effected
爲空呢?
Map<String,Map<String,Boolean>> wrapMap = new HashMap<>();
wrapMap.put("innerMap",new HashMap<>());
boolean effected = wrapMap.get("innerMap").get("effected");
// StackTrace:
Exception in thread "main" java.lang.NullPointerException
at org.example.App.main(App.java:50)
複製代碼
JAVA 14 也 get 到了 JAVAER 們的痛點,優化了 NullPointerException 的提示,讓你不在困惑,一眼就能定位到底「空」在哪!
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.lang.Boolean.booleanValue()" because the return value of "java.util.Map.get(Object)" is null
at org.example.App.main(App.java:50)
複製代碼
如今的 StackTrace 就很直觀了,直接告訴你 effected
變量爲空,不再用困惑!
在以前的版本中,JAVA 若是想操做堆外內存(DirectBuffer),還得 Unsafe 各類 copy/get/offset。如今直接增長了一套安全的堆外內存訪問接口,能夠輕鬆的訪問堆外內存,不再用搞 Unsafe 的騷操做了。
// 分配 200B 堆外內存
MemorySegment memorySegment = MemorySegment.allocateNative(200);
// 用 ByteBuffer 分配,而後包裝爲 MemorySegment
MemorySegment memorySegment = MemorySegment.ofByteBuffer(ByteBuffer.allocateDirect(200));
// MMAP 固然也能夠
MemorySegment memorySegment = MemorySegment.mapFromPath(
Path.of("/tmp/memory.txt"), 200, FileChannel.MapMode.READ_WRITE);
// 獲取堆外內存地址
MemoryAddress address = MemorySegment.allocateNative(100).baseAddress();
// 組合拳,堆外分配,堆外賦值
long value = 10;
MemoryAddress memoryAddress = MemorySegment.allocateNative(8).baseAddress();
// 獲取句柄
VarHandle varHandle = MemoryHandles.varHandle(long.class, ByteOrder.nativeOrder());
varHandle.set(memoryAddress, value);
// 釋放就這麼簡單,想一想 DirectByteBuffer 的釋放……多奇怪
memorySegment.close();
複製代碼
不瞭解 Unsafe 操做堆外內存方式的同窗,能夠參考個人另外一篇文章《JDK中爲了性能大量使用的Unsafe類,你會用嗎?》
以前若是想構建一個可執行的程序,還須要藉助三方工具,將 JRE 一塊兒打包,或者讓客戶電腦也裝一個 JRE 才能夠運行咱們的 JAVA 程序。
如今 JAVA 直接內置了 jpackage
打包工具,幫助你一鍵打包二進制程序包,終於不用亂折騰了
在 JAVA 15中,ZGC 和 Shenandoah 不再是實驗功能,正式登錄了(不過 G1 仍然是默認的)。若是你升級到 JAVA 15 之後的版本,就趕快試試吧,性能更強,延遲更低
JAVA 的繼承目前只能選擇容許繼承和不容許繼承(final 修飾),如今新增了一個封閉(Sealed )類的特性,能夠指定某些類才能夠繼承:
public sealed interface Service permits Car, Truck {
int getMaxServiceIntervalInMonths();
default int getMaxDistanceBetweenServicesInKilometers() {
return 100000;
}
}
複製代碼
JAVA 16 在用戶可見的地方變化並很少,基本都是 14/15 的實驗性內容,到了 16 正式發佈,這裏就不重複介紹了。
以上介紹的各類新特性,有些特性在歷史版本中還屬於實驗性功能,不過按照 JAVA 目前這個驢同樣的更新頻率,極可能下個版本就是穩定版了。早學早享受,晚學被捲走……
看看時間,300 秒到了嗎?
原創不易,禁止未受權的轉載。若是個人文章對您有幫助,就請點贊/收藏/關注鼓勵支持一下吧❤❤❤❤❤❤