Java16新特性2021年3月16日,甲骨文正式发布Java16!思考JDK1的新场景和生动性。什么叫光阴似箭,沧海桑田。虽然目前Java8依然统治着大部分场合,但我想各位Javaer应该对Java16的新特性很感兴趣吧!看完之后,我觉得这次更新还是很有意思的,所以我就挑选几个Java16的新特性,让大家过饱眼福!(可以自己建个项目试试)支持模式匹配的instanceof想想你是怎么用instanceof的,举个例子:if(objinstanceofString){Strings=(String)obj;//grr……}是不是这个代码烦人,我知道是String,强行给,应该可以改进~if(objinstanceofStrings){//这里s随便用,从类型判断,到变量定义,类型转换,一应俱全去吧,你快乐吗?更进一步,也可以这样使用。判断条件中可以直接使用模式变量sif(objinstanceofStrings&&s.length()>5){flag=s.contains("jdk");}但是要注意,下面的用法是错误的(我就不解释了进一步的原因):if(objinstanceofStrings||s.length()>5){//Error!...}Recordstype我们对Java最大的看法是什么?当然太麻烦了,一个简单的函数,重的语法就要几十行,别着急,改进来了,看看新的Recodes类型吧!假设你现在有这样一个类:这是一个典型的不可变数据对象,equals()方法、hashCode()方法、toString()方法其实比较通用。但是我们必须为它多写几行代码。虽然有IDE的大力协助,但看起来还是不是很爽(如果没有IDE,我会哭得更厉害)。不过没关系,记录就在这里!用Records来表示上面的类,只需要:recordPoint(intx,inty){}是不是很简单,感觉很清爽?记录类不同于普通类,它会帮你隐式生成一些字段和构造函数。例如,上面的记录将被编译成这样:recordPoint(intx,inty){//隐式生成字段privatefinalintx;privatefinalinty;//隐式生成所有参数的构造函数Point(intx,inty){this.x=x;this.y=y;}}ZGC并发线程处理ZGC即TheZGarbageCollector,JDK11中引入的低延迟垃圾收集器,试图解决GC的痛点,即暂停。同时,也将面向以TB为单位的超大规模内存。在Java16中,许多由ZGC的线程堆栈处理的操作已从检查点移至并发阶段,这意味着停顿更少。(后面准备出一篇zgc相关的文章,顺便测一下这次暂停优化的长度)弹性元空间在Java虚拟机中,元空间用于存放一些类的元信息,并且元空间中的数据可以被垃圾收集。但不幸的是,空闲未使用的元空间不会返回给操作系统,这会导致内存浪费。这个新特性就是为了解决这个问题,它允许虚拟机从元空间中归还未使用的内存,从而更有效地使用物理内存。同时有一个新的虚拟机参数可以用来控制这个rec??laim的执行强度:-XX:MetaspaceReclaimPolicy=(balanced|aggressive|none)UnixDomainsocketUnixDomainsocket本身提供了一套兼容网络编程,而是一种更可靠、高效、安全的进程间通信方式,不需要经过网络协议栈,不需要加包解包、计算校验和、维护序列号和回复等.,只是将应用层数据从一个进程复制到另一个进程。在Java16中,这个socket已经可以直接使用了(Unix-domain(AF_UNIX),虽然叫UNIXsocket,windows10和WindowsServer2019也可以使用)。为了支持Unix域套接字,添加了一个特殊的java.net.UnixDomainSocketAddress类。我们来看看它的使用:新的打包工具提供了一个新的打包工具jpackage,用于打包独立的Java应用。这个工具可以在windows上生成exe和msi,在macOS上生成pkg和dmg,在linux上生成deb和rpm。为用户提供一键安装Java程序是一种很好的方式。比如对于非模块化的应用,可以这样打包:jpackage--namemyapp--inputlib--main-jarmain.jar或者直接指定mainclassjpackage--namemyapp--inputlib--main-jarmain.jar--main-classmyapp。主要针对模块化应用:jpackage--namemyapp--module-pathlib-mmyapp或者直接指定mainclassjpackage--namemyapp--module-pathlib-mmyapp/myapp.Main值对象错误使用警告值对象,如java.lang。Integer、java.lang.Double等不可变对象在废弃构造函数的基础上进一步标记为forRemoval(不要再使用它们的构造函数了!)。同时,如果在值对象上进行synchronize,则会被warn,例如:Doubled=20.0;synchronized(d){...}//javac和hotsopt都会warnObjecto=d;synchronized(o){...}//HotSpot会在虚拟机级别进行警告,同时也提供了参数来控制虚拟机级别的报错行为:-XX:DiagnoseSyncOnValueBasedClasses=1将这种同步行为视为致命错误-XX:DiagnoseSyncOnValueBasedClasses=2打开日志,在控制台登录这个同步行为记录在飞行记录器中。默认限制是使用JDK内部API。对于一些JDK内部API,做了更严格的限制。例如,com.sun.*、jdk.*、org.*包中的API,从Java16开始默认禁用。因此,鼓励大家使用标准API,而不是内部API(点此查看可以替换的内部API)。例如下面的代码在Java16中会报错:System.out.println(sun.security.util.SecurityConstants.ALL_PERMISSION);错误示例:Exceptioninthread"main"java.lang.IllegalAccessError:classTest(inunnamedmodule@0x5e481248)cannotaccessclasssun.security.util.SecurityConstants(inmodulejava.base)becausemodulejava.basedoesnotexportsun.security.utiltounnamedmodule@0x5e481248同时,JDK还提供了——-illegal-access参数控制内部API的使用:--illegal-access=permit允许使用内部API--illegal-access=warn允许使用内部API,但是每次使用都会得到一个警告--illegal-access=debug允许使用内部API,并更详细地打印每个错误的调用堆栈。有了它,您就可以找到自己调用错误的地方,并且可以修复那些不合适的地方。使用--illegal-access=deny禁止使用内部API孵化项目:VectorAPI我们知道像Go这样的后起之秀,内部已经使用了AVX指令,性能直线上升。Java在这方面也不甘示弱,而在Java16中,vectorAPI作为一个孵化项目,让我们可以直接使用SIMD指令来提升性能(如果使用得当,这一波会把你带走)。让我们来看看!这是一个简单的标量计算:voidscalarComputation(float[]a,float[]b,float[]c){for(inti=0;i
