点赞再看,养成好习惯
JAVA 这几年的更新实在是太太太……快了,JAVA 8 都还没用多久,16 都已经发布了。自从 JAVA 8 发布了 Lambda 和 Stream 以后,JAVA 就像打了鸡血同样,半年一个版本的发布,生产队的驴也没这么勤快。
java
致使咱们如今彻底跟不上 JAVA 发布的节奏,我司目前还停留在 JAVA 8,甚至部分老系统还在使用 JAVA 7,根本不能轻易的升级。
json
不过虽然暂时用不上最新版本的 JAVA,但了解每一个新版本的主要特性仍是很重要的,否则哪天真跟着升级了,那还不得一脸懵逼。
安全
本文就带你快速了解 JAVA 9 - 16 的主要新特性,早学完早下班!bash
JAVA 8 对接口增长了默认方法的支持,在 JAVA 9 中对该功能又来了一次升级,如今能够在接口里定义私有方法,而后在默认方法里调用接口的私有方法。
函数
这样一来,既能够重用私有方法里的代码,又能够不公开代码工具
public interface TestInterface { default void wrapMethod(){ innerMethod(); } private void innerMethod(){ System.out.println(""); } }
JAVA 5 就引入了泛型(generic),到了 JAVA 7 开始支持钻石(diamond)运算符:<>
,能够自动推断泛型的类型:post
List<Integer> numbers = new ArrayList<>();
可是这个自动推断类型的钻石运算符可不支持匿名内部类,在 JAVA 9 中也对匿名内部类作了支持:性能
List<Integer> numbers = new ArrayList<>() { ... }
try-with-resources
JAVA 7 中增长了try-with-resources
的支持,能够自动关闭资源:优化
try (BufferedReader bufferReader = new BufferedReader(...)) { return bufferReader.readLine(); }
但须要声明多个资源变量时,代码看着就有点恶心了,须要在 try 中写多个变量的建立过程:spa
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 秒到了吗?
> 原创不易,禁止未受权的转载。若是个人文章对您有帮助,就请点赞/收藏/关注鼓励支持一下吧❤❤❤❤❤❤