背景
持续更新记录Jvav(Java)的新版本特性和使用案例
JDK19 新版本总共包含 7 个新的 JEP:
虚拟线程 1 2 var virtualThread = Thread.ofVirtual().unstarted(() -> System.out.println(Thread.currentThread())); virtualThread.start();
JDK18 JDK 18 共包括 9 个 JEP,以及数百个较小的增强功能和一千多个错误修复。
该版本中并没有增加很多新特性,只是对GC、加密、安全库、字符集、I/O做一些改进
JDK17 JDK/Java 17 总共包含 14 个 JEP,具体如下:
sealed关键字
被 sealed 修饰,说明它是一个密封类,并且只允许指定的 子类继承。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package com.example.jdk17;public abstract sealed class Shape permits Circle, Rectangle { }public final class Rectangle extends Shape { }public final class Circle extends Shape { }public final class Start extends Shape { }
Stream类改进 Random类改进 JDK16
Mentioned Below are Some of the New Features Added in Java 16:
Foreign Linker API
Warnings for Value-Based Classes
Strong Encapsulation
Moving Z Garbage Collector Thread-Stack Processing
A Flexible Metaspace Capability
Added C++ 14 Language Features
Records Classes
A Vector API
Pattern Matching
jpackage Tool for Packaging Self-Contained Java Applications.
OpenJDK source code repositories Migration from Mercurial to Git.
JDK15 ZGC转正 JDK14 Record关键字 Java 编译器将为 record 类型生成 equals(),hashCode(),toString() 方法,以及生成适当的构造函数,并且为所有字段生成 getter 和 setter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public record Point (double x, double y) { }public class Point { private final double x; private final double y; public Point (double x, double y) { this .x = x; this .y = y; } public double getX () { return x; } public double getY () { return y; } }
有用信息空指针异常 通过 JVM 参数中添加
1 -XX:+ShowCodeDetailsInExceptionMessages
可以在空指针异常中获取更为详细的调用信息,更快的定位和解决问题。
接口类型匹配 1 2 3 4 if (o instanceof String) { String s = (String)o; System.out.println(s.length); }
自动转换
1 2 3 4 Object o = null ; if (o instanceof String s) { System.out.println(s.length()); }
JDK13 文本块 1 2 3 4 5 6 7 String htmlBlock = """ <html> <body> <p>My web page</p> </body> <html> """ ;
String类增强 1 2 3 formatted(): This formats the string using the string itself as the format string and is equivalent to calling format (this , args) stripIndent(): This removes incidental spaces from the string. This is useful if you are reading multi-line strings and want to apply the same elimination of incidental whitespace as happens with an explicit declaration. translateEscapes(): This returns the string with escape sequences, (e.g. r) translated into the appropriate Unicode value.
JDK12 Switch 表达式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 var day = MONDAY;int numLetters = 0 ;switch (day) { case MONDAY: case FRIDAY: case SUNDAY: numLetters = 6 ; break ; case TUESDAY: numLetters = 7 ; break ; case THURSDAY: case SATURDAY: numLetters = 8 ; break ; case WEDNESDAY: numLetters = 9 ; break ; default : throw new IllegalStateException ("Huh? " + day); }
新版本
1 2 3 4 5 6 7 int numLetters = switch (day) { case MONDAY, FRIDAY, SUNDAY -> 6 ; case TUESDAY -> 7 ; case THURSDAY, SATURDAY -> 8 ; case WEDNESDAY -> 9 ; default -> throw new IllegalStateException ("Huh? " + day); };
JDK11 局部变量引入Lambda 1 2 3 list.stream() .map((var s) -> s.toLowerCase()) .collect(Collectors.toList());
String类增强 1 2 3 4 5 6 boolean isBlank () : Returns true if the string is empty or contains only white space codepoints, otherwise false . Stream lines () : Returns a stream of lines extracted from this string, separated by line terminators. String repeat (int ) : Returns a string whose value is the concatenation of this string repeated count times. String strip () : Returns a string whose value is this string, with all leading and trailing whitespace removed. String stripLeading () : Returns a string whose value is this string, with all leading whitespace removed. String stripTrailing () : Returns a string whose value is this string, with all trailing whitespace removed.
ZGC 这是一种新的实验性垃圾收集器,设计用于需要大(数GB)堆和低延迟的应用程序。它使用一个单代堆,并与应用程序同时执行大多数(但不是全部)GC工作。它通过使用一个读取屏障来实现这一点,该屏障拦截应用程序对对象的每次读取,并确保返回的引用是正确的。这消除了在应用程序线程运行时能够同时重新定位对象的问题。
ZGC基于区域(如G1),支持NUMA并进行压缩。它不打算用作通用收集器。
JDK10 var关键字 局部变量类型自动推断
1 2 var list = new ArrayList <String>(); var stream = list.stream();
集合增强 List,Set,Map 提供了静态方法copyOf()
返回入参集合的一个不可变拷贝。
1 2 3 static <E> List<E> copyOf (Collection<? extends E> coll) { return ImmutableCollections.listCopy(coll); }
G1并行Full GC JDK9 接口中允许私有方法 1 2 3 4 5 interface Intf { private void m (String s) { System.out.println(s); } }
集合工厂方法 1 2 3 Set<Integer> set = Set.of(1 , 2 , 3 ); List<Integer> list = List.of(1 , 2 , 3 ); Map<String, Integer> map = Map.of("one" , 1 , "two" , 2 );
try-with-resources 增强 jdk9之前只能在try-with-resources里声明变量
1 2 3 4 5 try (FileInputStream file = new FileInputStream ("a.txt" )){ file.read(); }catch (Exception e){ e.printStackTrace(); }
jdk9后可以在外面写
1 2 3 4 5 6 7 FileInputStream file = new FileInputStream ("a.txt" ); try (file){ file.read(); }catch (Exception e){ e.printStackTrace(); }
响应式流 新增了 java.util.concurrent .Flow
类
模块化 模块化的出现主要是为了减少包的大小,对不同模块的权限控制更加精细
1 2 3 4 5 [open] module <module > { <module -statement>; <module -statement>; ... }
open修饰符是可选的,它声明一个开放的模块。 一个开放的模块导出所有的包,以便其他模块使用反射访问。 是要定义的模块的名称。 是一个模块语句。 模块声明中可以包含零个或多个模块语句。 如果它存在,它可以是五种类型的语句之一:
导出语句(exports statement);
开放语句(opens statement);
需要语句(requires statement);
使用语句(uses statement);
提供语句(provides statement)。
参考:https://openjdk.org/projects/jigsaw/quick-start
进程 API 新增了java.lang .ProcessHandle
类获取进程相关信息
1 2 3 4 5 6 7 8 9 public class ProcessDemo { public static void main (String[] args) { ProcessHandle currentProcess = ProcessHandle.current(); System.out.println("进程pid =" +currentProcess.pid()); System.out.println("进程信息" +currentProcess.info()); } }
Jshell 可实现java控制台代码交互式编程(类似输入脚本)
JDK8 函数式接口 该库位于java.util.function
包下,可以将函数作为参数进行传递、运行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package java8;import java.util.function.Function;public class FunctionDemo { public static void main (String[] args) { Function<String, String> function = new Function <>() { @Override public String apply (String s) { return String.format("modify %s" ,s); } }; System.out.println(function.apply("hello" )); m0(function); } public static void m0 (Function<String,String> function) { String s = "hello" ; function.apply(s); } }
Lambda表达式 lambda语法糖减少一定的代码量,格式
1 (parameters) -> expression 或 (parameters) ->{ statements; }
Java 8 中 Consumer, Supplier, Predicate and Function的应用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class Lambda { interface itf { void m (String s) ; } public static void main (String[] args) { itf itf0 = new itf () { @Override public void m (String s) { System.out.println(s); } }; itf itf1 = s -> System.out.println(s); itf0.m("hello0" ); itf1.m("hello1" ); } }
Stream 该库位于java.util.stream
包下
1 2 3 4 5 6 7 8 9 10 11 public class StreamDemo { public static void main (String[] args) { int [] arr = {1 , 3 , 3 , 4 , 4 , 5 , 55 , 3 }; Stream<String> stream = Stream.of(args); stream.map(s -> s); stream.collect(Collectors.toList()); stream.filter(s->s.equals(0 )); stream.flatMapToInt(e-> IntStream.of(e.length())).forEach(System.out::println); } }
Optional Optional的出现是为了解决NPE问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import java.util.Optional;public class OptionalDemo { public static void main (String[] args) { String s0 = null ; s0 = Optional.ofNullable(s0).orElse("hello" ); System.out.println(s0); String s1 = "abc" ; s1 = Optional.ofNullable(s1).orElse("hello" ); System.out.println(s1); String s2 = null ; s2 = Optional.of(s2).orElse("hello" ); System.out.println(s2); String s3 = "hi" ; s3 = Optional.ofNullable(s3).map(s -> s.substring(1 , 2 )).orElse("Hi" ); System.out.println(s3); } }
Date Time API 新增了LocalDate
、LocalDateTime
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import java.time.LocalDate;import java.time.LocalDateTime;import java.time.format.DateTimeFormatter;public class DateDemo { public static void main (String[] args) { LocalDate date = LocalDate.now(); date.isBefore(date); String format = date.format(DateTimeFormatter.ISO_ORDINAL_DATE); System.out.println(format); LocalDateTime time = LocalDateTime.now(); int year = time.getYear(); System.out.println(year); } }
Nashorn javascript引擎 资料 jvav8:https://www.oracle.com/java/technologies/javase/8-whats-new.html jvav18: https://www.oracle.com/java/technologies/javase/18-relnote-issues.html#NewFeature