?有多少小伙伴用著 JDK8 卻寫著 JDK6 的代碼
有多少小伙伴在用著 JDK8 卻寫著 JDK6 的代碼,松哥最近在連載 WebFlux,深感 JDK8 中的 Lambda、函數(shù)式接口,JDK9 中的 FlowAPI 的重要,因此一直想整篇文章和大家梳理下從 JDK8 開始 Java 的一些變化,剛好最近在網(wǎng)上看到這篇文章,就順手和大家分享下。
JAVA 這幾年的更新實(shí)在是太太太……快了,JAVA 8 都還沒用多久,16 都已經(jīng)發(fā)布了。自從 JAVA 8 發(fā)布了 Lambda 和 Stream 之后,JAVA 就像打了雞血一樣,半年一個(gè)版本的發(fā)布,生產(chǎn)隊(duì)的驢也沒這么勤快。

導(dǎo)致我們現(xiàn)在完全跟不上 JAVA 發(fā)布的節(jié)奏,我司目前還停留在 JAVA 8,甚至部分老系統(tǒng)還在使用 JAVA 7,根本不能輕易的升級(jí)。
JAVA 9(2017年9月)
接口里可以添加私有接口
public interface TestInterface {
default void wrapMethod(){
innerMethod();
}
private void innerMethod(){
System.out.println("");
}
}
匿名內(nèi)部類也支持鉆石(diamond)運(yùn)算符
<>,可以自動(dòng)推斷泛型的類型:List<Integer> numbers = new ArrayList<>();
List<Integer> numbers = new ArrayList<>() {
...
}
增強(qiáng)的 try-with-resources
try-with-resources的支持,可以自動(dòng)關(guān)閉資源:try (BufferedReader bufferReader = new BufferedReader(...)) {
return bufferReader.readLine();
}
try (BufferedReader bufferReader0 = new BufferedReader(...);
BufferedReader bufferReader1 = new BufferedReader(...)) {
return bufferReader0.readLine();
}
BufferedReader bufferReader0 = new BufferedReader(...);
BufferedReader bufferReader1 = new BufferedReader(...);
try (bufferReader0; bufferReader1) {
System.out.println(br1.readLine() + br2.readLine());
}
JAVA 10(2018年3月)
局部變量的自動(dòng)類型推斷(var)
var,它可以自動(dòng)推斷局部變量的類型,以后再也不用寫類型了,也不用靠 lombok 的 var 注解增強(qiáng)了var message = "Hello, Java 10";
JAVA 11(2018年9月)
Lambda 中的自動(dòng)類型推斷(var)
var 這個(gè)自動(dòng)類型推斷的變量,通過 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");
javac + java 命令一把梭
$ java HelloWorld.java
Hello Java 11!
Java Flight Recorder 登陸 OpenJDK
JAVA 12(2019年3月)
更簡(jiǎn)潔的 switch 語(yǔ)法
switch 語(yǔ)法還是比較啰嗦的,如果多個(gè)值走一個(gè)邏輯需要寫多個(gè) 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";
}
typeOfDay = switch (dayOfWeek) {
case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> "Working Day";
case SATURDAY, SUNDAY -> "Day Off";
};
instanceof + 類型強(qiáng)轉(zhuǎn)一步到位
instanceof 判斷一下,然后再?gòu)?qiáng)轉(zhuǎn)為該類型處理:Object obj = "Hello Java 12!";
if (obj instanceof String) {
String s = (String) obj;
int length = s.length();
}
instanceof 支持直接類型轉(zhuǎn)換了,不需要再來(lái)一次額外的強(qiáng)轉(zhuǎn):Object obj = "Hello Java 12!";
if (obj instanceof String str) {
int length = str.length();
}
JAVA 13(2019年9月)
switch 語(yǔ)法再增強(qiáng)
swtich 語(yǔ)法,但并不能在 -> 之后寫復(fù)雜的邏輯,JAVA 12 帶來(lái)了 swtich更完美的體驗(yàn),就像 lambda 一樣,可以寫邏輯,然后再返回:typeOfDay = switch (dayOfWeek) {
case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> {
// do sth...
yield "Working Day";
}
case SATURDAY, SUNDAY -> "Day Off";
};
文本塊(Text Block)的支持
String json = "{\"id\":\"1697301681936888\",\"nickname\":\"空無(wú)\",\"homepage\":\"https://juejin.cn/user/1697301681936888\"}";
String json = """
{
"id":"1697301681936888",
"nickname":"空無(wú)",
"homepage":"https://juejin.cn/user/1697301681936888"
}
""";
JAVA 14(2020年3月)
新增的 record 類型,干掉復(fù)雜的 POJO 類
recordpublic record UserDTO(String id,String nickname,String homepage) { };
public static void main( String[] args ){
UserDTO user = new UserDTO("1697301681936888","空無(wú)","https://juejin.cn/user/1697301681936888");
System.out.println(user.id);
System.out.println(user.nickname);
System.out.println(user.id);
}

更直觀的 NullPointerException 提示
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)
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)
effected 變量為空,再也不用困惑!安全的堆外內(nèi)存讀寫接口,別再玩 Unsafe 的騷操作了
// 分配 200B 堆外內(nèi)存
MemorySegment memorySegment = MemorySegment.allocateNative(200);
// 用 ByteBuffer 分配,然后包裝為 MemorySegment
MemorySegment memorySegment = MemorySegment.ofByteBuffer(ByteBuffer.allocateDirect(200));
// MMAP 當(dāng)然也可以
MemorySegment memorySegment = MemorySegment.mapFromPath(
Path.of("/tmp/memory.txt"), 200, FileChannel.MapMode.READ_WRITE);
// 獲取堆外內(nèi)存地址
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);
// 釋放就這么簡(jiǎn)單,想想 DirectByteBuffer 的釋放……多奇怪
memorySegment.close();
新增的 jpackage 打包工具,直接打包二進(jìn)制程序,再也不用裝 JRE 了
jpackage 打包工具,幫助你一鍵打包二進(jìn)制程序包,終于不用亂折騰了JAVA 15(2020年9月)
ZGC 和 Shenandoah 兩款垃圾回收器正式登陸
封閉(Sealed )類
public sealed interface Service permits Car, Truck {
int getMaxServiceIntervalInMonths();
default int getMaxDistanceBetweenServicesInKilometers() {
return 100000;
}
}
JAVA 16(2021年3月)
總結(jié)
END
順便給大家推薦一個(gè)GitHub項(xiàng)目,這個(gè) GitHub 整理了上千本常用技術(shù)PDF,絕大部分核心的技術(shù)書籍都可以在這里找到,
GitHub地址:https://github.com/javadevbooks/books
Gitee地址:https://gitee.com/javadevbooks/books
電子書已經(jīng)更新好了,你們需要的可以自行下載了,記得點(diǎn)一個(gè)star,持續(xù)更新中..
評(píng)論
圖片
表情

