JDK 14 也就是我们说的 Java14 发布了,那你已经了解到了它有哪些新的特性了吗?
这次在新的 Java14 中加入了非常多的语法糖,这可以使得我们在编程过程中更加的快捷,写出来的代码也会更加简介一些。话不多说,我们马上来看看这次更新了哪些新特性吧!
在 Java 14 之前我们需要这样写代码:
Object object = someOneObj(); if(object instanceof String){ boolean isContainsA = ((String) object).contains("A"); }
Object object = someOneObj(); if (object instanceof String str) { // 注意这里更换了变量名 boolean isContainsA = str.contains("A"); } // 还能继续加入判断条件 if (object instanceof String str && str.contains("A")) { System.out.println(str); }
以前我们写 switch case 是这样的:
String day = getDay(); switch (day) { case "周一": case "周二": System.out.println("这里是周一和周二"); break; case "周三": System.out.println("这里是周三"); break; case "周四": System.out.println("这里是周四"); break; default: System.out.println("这里是周五六日"); break; }
String day = getDay(); switch (day) { case "周一", "周二" -> System.out.println("这里是周一和周二"); case "周三" -> System.out.println("这里是周三"); case "周四" -> System.out.println("这里是周四"); default -> System.out.println("这里是周五六日"); }
boolean isWorkday = switch (day) { case "周六", "周日" -> false; default -> true; };
boolean isWorkday = switch (day) { case "周六", "周日" -> false; default -> { boolean isWeekend = isWeekend(day); yield isWeekend;// 这2行可以合并省略变量,为了解释留下的 } };
以前我们构造一个 class, 按照规范需要写get,set,equals,hashcode等方法:
public class SomeClass { private String stringField; private int intField; public SomeClass(String stringField, int intField) { this.stringField = stringField; this.intField = intField; } public String getStringField() { return stringField; } public void setStringField(String stringField) { this.stringField = stringField; } public int getIntField() { return intField; } public void setIntField(int intField) { this.intField = intField; } // 剩下的equals toString hashcode 等方法... }
record SomeClass(String strFiled, int intFiled) { // 它会自动生成equals,tostring,hashcode get/set等方法 }
注意:
record 是修饰在 class 名的,不是构造函数,也就是说你不用再写 public class SomeClass 了。
它所有修饰的字段是final类型的,基础数据类型不可以再更改值,但是对象可以更改内部字段。
它默认继承了Record类,所以不能再继承其他类了,所生成的类也是final类型的。
可以继续增加静态属性:
record SomeClass(String strFiled, int intFiled) { static int number = 1; }
以前我们写长长的字符串,需要这样写:
String str = "<html>" + "<header>" + "</header>" + "<body>" + "<div>body</div>" + "</body>" + "</html>";
// 注意 """ 之后必须换行 String str = """ <html> <header> </header> <body> <div>"body"</div> </body> </html> """;
以前NPE报错只报哪一行:
line 1 User user = someUser(); line 2 user.getChild().getName().someMethod();
比如你收到 line 2 出现了 NPE, 那你知道是user为null呢?还是user的child为null呢?还是他的name为null呢?
Exception in thread "main" java.lang.NullPointerException: Cannot read field 'user' because 'user.getChild()' is null. at Prog.main(Prog.java:5)
Java NIO(New IO)JDK 1.4以来就存在,FileChannel使用MappedByteBuffer将文件数据的一部分加载到虚拟内存中,然后引入了新的增强,称为Path。Path是一个接口,当我们在java NIO中工作时,它将java.io.File类替换为文件或目录的表示。
现在JEP的目标是在MappedByteBuffer中进行增强,以便 non-volatile memory (NVM)中加载文件数据的部分。在这种存储器中,即使像ROM(只读存储器)、Flash存储器、硬盘等存储设备关闭电源,数据也不会丢失/删除;在non-vllatile的情况下,如果像RAM一样关闭电源,数据也不会保留。唯一需要更改的API是FileChannel客户端使用的新枚举,用于请求位于NVM支持的文件系统(而不是传统的文件存储系统)上的文件的映射。
此实现允许通过ByteBuffer将NVM作为堆外资源进行管理。一个相关的增强,JDK-8153111,正在研究对堆数据使用NVM。可能还需要考虑使用NVM来存储JVM元数据。这些不同的NVM管理模式在结合使用时可能不兼容,或者可能只是不合适。该API只能处理高达2GB的映射区域。可能需要修改建议的实现,使其符合JDK-8180628中建议的更改,以克服此限制。
Java 14 计划引入打包功能,以简化依赖于各种依赖项的安装过程。有时仅仅提供一个JAR文件是不够的;它必须提供一个适合本地/本机的可安装工具包。打包工具还可以帮助填补其他技术留下的空白。
jpackage工具将Java应用程序捆绑到一个特定于平台的包中,该包包含所需的所有依赖项。作为一组普通的JAR文件或模块集合。支持的特定于平台的包格式包括:
Linux:deb和rpm
macOS:pkg和dmg
Windows:msi和exe
非均匀存储器访问(Non-uniform memory accession,NUMA)是一种将微处理器集群配置成多处理系统的方法,可以实现内存的局部共享,提高系统性能,扩展系统能力。
Java 14正计划实现支持NUMA的内存分配,以提高大型计算机上的G1性能。
G1的堆被组织为固定大小区域的集合。一个区域通常是一组物理页面,但是当使用大页面(via-XX:+UseLargePages)时,几个区域可以组成一个物理页面。
如果指定了 +XX:+UseNUMA 选项,那么当JVM初始化时,区域将均匀地分布在可用的NUMA节点总数上。
Java 14 正计划提供一个API,通过该API,JDK飞行记录器(JFR)收集的数据将连续监视进程内和进程外应用程序。
可以以非流式方式记录相同的事件集,如果可能的话,开销小于1%。因此,事件流将与非流同时执行。
jdk.jfr模块中的jdk.jfr.consumer包扩展了异步订阅事件的功能。
废除了 Solaris / SPARC, Solaris / x64, and Linux / SPARC, 并会在以后的版本中彻底移除
移除了CMS垃圾回收器
给windows和macOS新增了特定垃圾回收器
废除了并行清楚和串行GC( ParallelScavenge + SerialOld GC )组合
移除了pack200 相关工具和api