Java14新特性
Java14 上个月发布了,官方解读:https://openjdk.java.net/projects/jdk/14/
先中文翻译一下:
下面验证一下Java14"真香定律"~
一 、准备工作
安装JDK14;
IDEA最新版的(2020.1版以后的,旧版可能不支持,其他编辑器没试过)
二 、新特性
①Pattern Matching for instanceof (Preview) 模式匹配
Object obj = "java14"; //测试一把 if (obj instanceof String sss && sss.length() > 5) { System.out.println(sss.contains("b")); System.out.println("这是字符串!sss" + sss); } else { System.out.println("其他~"); }
在 instanceof 后面直接可以转换类型, 不用再将Object转成String,言简意赅。
②Packaging Tool (Incubator) 打包工具
这里主要是提供一种像安装程序的方式类似的安装体验,针对之前可运行的 .jar 文件,提供一种面向不同 os 的打包格式的工具,这个工具可以支持 Windows 下的 msi 和 exe 格式、 linux 下的 dep 和 rpm 格式以及 Mac 下的 pkg 和 dmg 格式,这里除了打包之后有一个通用的系统的安装体验之外,还能将一些 main 函数启动的初始入参固化到打包之后的文件中。
整体打包的命令会根据是否是做了模块化有所区别,分别是:
jpackage --name myapp --input lib --main-jar main.jar
以及
jpackage --name myapp --module-path lib -m myapp
可以通过 --type 来指定打包之后的格式,比如上述命令后面加入 --type dmg ,就是打包出 dmg 格式的安装包;
这个工具的动机主要是之前直接运行jar文件的方式需要使用方关心三个问题:
1、lib 的路径;
2、是否有显性的 main 函数指定和声明;
3、main 函数的入参;
这个工具可以简化 jar 文件使用的门槛;;(---摘抄于大佬原话)
③ NUMA-Aware Memory Allocation for G1 针对G1的NUMA感知内存分配
这个点是基于 G1 垃圾回收器的,主要是针对年轻代的对象内存分配做了一个优化,提高的是 CPU 计算过程中的内存访问速度;
NUMA 是 non-unified memory access 的缩写,主要是指在当前的物理机中,比较普遍是多核的,这样每个核对于每一块或者某一区域的内存访问速度会随着核和物理内存所在的位置的远近而有不同的时延差异(在同一块物理 scoket 上的 cpu 对于不同距离的内存访问基本时延相同),这个就是这个优化的一个大前提;
然后在 Java 中,堆内存分配一般发生在线程运行的时候,new 了一个新对象,然后该线程会触发 G1 去 allocate 一块内存出来,用来存放新的对象,在 G1 中,其实就是一块region(大对象除外,大对象需要多个 region ,但是不在这个优化的范畴中),那其实就在这个 allocation 分配新内存的过程中,优先在当前线程所绑定的同个 NUMA node 内存,因为是基于同一个线程中创建的对象大部分是短存活并且高概率互相调用的,如果没有足够的可分配内存,就会触发一次 YGC 。
这个点的优化,个人感觉性能优化可能比较有限;(---摘抄于大佬原话)
④JFR Event Streaming JFR事件流
JFR事件流 提供了一个API,用于持续使用来自流程内和流程外应用程序的JFR数据。
JFR是用于收集有关正在运行的Java应用程序的概要分析和诊断数据的工具。事件流建议记录与非流情况相同的事件集,并且如果可能,开销小于百分之一。事件流必须与基于磁盘和基于内存的非流记录共存。
在这种情况下,HotSpot VM使用JFR发出500个以上的数据点,而其中的大多数数据仅可通过分析日志文件来使用,因此很容易激发这种提议。当前,用户必须开始录制,停止录制,将内容转储到磁盘,然后解析录制文件。这对于应用程序概要分析非常有效,但不适用于监视目的。监控使用情况的一个实例是显示动态更新数据的仪表板。创建记录会产生开销,例如将数据从磁盘存储库复制到单独的记录文件。如果有一种方法可以在不创建新记录文件的情况下从磁盘存储库中读取正在记录的数据,则可以避免很多开销。
⑤Helpful NullPointerExceptions 有用的空指针
以前的空指针只会定位到一行(生产环境让人抓狂),现在可以定位到具体的哪一个对象为null。
注意:调试时候需要加参数: -XX:+ShowCodeDetailsInExceptionMessages
⑥Switch Expressions Switch表达式
以前的switch里面,一个case后面接一个break;(考试题经常省略break来忽悠学僧) 。现在可以直接写
⑦Records 记录类
跟正常使用的javabean稍有区别,record标识后是一个final修饰的类,不能被继承
有时候遇到一些简单的数据载体,比如用到Person类,只有两个属性,age和name。
创建一个类后正常的做法(或者借助于lombock插件):
- toString()方法
- hashCode() and equals()方法
- Getter 方法
- 一个共有的构造函数
现在你可以直接用record啦(就这么一行);
record Person(int age, String name) { }
然后使用:
Person person1 = new Person(10,"tom"); System.out.println(person1.toString()); //Person[age=10, name=tom] System.out.println(person1.age()); //10 System.out.println(person1.name()); //tom
⑧Text Blocks (Second Preview) 文本块
这个特性之前在 Java13 的时候出现过,preview,就是个偏实验测试的特性,这次在 14 中,依旧是 preview ,主要是扩展了两个 escape sequence ,分别是 “\” 和 “\s” , “\” 主要是用来明确标明换行的位置及之前的内容,主要是保留行末的空格,
如果拼接一个html的话,需要很多" " 和换行处理,格式看上去很丑~
String html = "<html>\n" + " <body>\n" + " <p>Hello, world</p>\n" + " </body>\n" + "</html>\n";
用文本块之后,看上去比较直观,也可以写SQL语句块。
String html = """ <html> <body> <p>Hello, world</p> </body> </html> """;
⑨ZGC on macOS & Windows
扩展 ZGC ,能够在 macOS 和 Windows (版本有限制)上使用,主要是兼容这两个系统和 linux 系统底层的内存映射机制的不同带来的差异;
⑩其他
·弃用Solaris和SPARC端口
·删除并发标记扫描(CMS)垃圾收集器
·弃用ParallelScavenge + SerialOld GC组合
·删除Pack200工具和API
·外部存储器访问API(孵化器)
三、总结
虽然目前Java8使用的比较多,但是关注一下Java发展趋势,看一下大佬们对Java未来的规划,我们从中可以受到一些启发。
参考: https://mp.weixin.qq.com/s/1F3Dr4_jdGZd3eqdhvdQZA , http://www.situedu.com/news/uid/3445.html