Java13新增特性

简介: Java13新增特性

一、小插曲


今天闲来无事,准备熟悉下JAVA13的新特性,就下载了jdk13版本。然后换了JDK,执行java -version 命令查看是否成功!结果执行命令报错了!在想是不是哪里出了问题。


然后去看了下安装目录看了下,见下图。发现......emmmmm...这好像和我认识的jdk不太一样啊。


20191003115052375.png


我有看了下java8的目录结构


20191003115841248.png



20191003115632252.jpg


目录结构为毛变了???jre呢!!!翻阅了资料,原来是因为在jdk9之后,安装jdk默认就不带jre了。原谅我一直在用java8.。。居然没有注意到这个点。如果需要jre的话。可以通过命令的方式进行生成。


首先以管理员的身份打开命令行,不然会没有权限。进入,jdk安装路径,我的是C:\Program Files\Java\jdk-13。执行


bin\jlink.exe --module-path jmods --add-modules java.desktop --output jre 命令。即可生成对应的jre目录。



20191003122046892.png


查看版本号。输出java13.


20191003122100459.png


不过之前报错不是因为没有jre。因为我路径搞错了。。。。20191003122228758.jpg



二、新功能和增强功能


结束了小插曲,我们进入正题。

现在统计数据来看,绝大部分企业还是Java 8,不会冒险升级,作为企业应用开发,Java8也足够了。


另外企业不用担心Oracle 版本的JDK收费问题。只要我们使用Open JDK代替Oracle JDK就可以


官网更新文档见https://www.oracle.com/technetwork/java/javase/13-relnote-issues-5460548.html


2.1、新增语法糖(预览版)

2.1.1Text Blocks

不得不说,我觉得这次新增语法块是真的好用。字符串可以像markDown一样的语法去写。

以前写法


String html = "<html>\n" +
              "    <body>\n" +
              "        <p>Hello, java</p>\n" +
              "    </body>\n" +
              "</html>\n";

现在写法

String html = """
              <html>
                  <body>
                      <p>Hello, java</p>
                  </body>
              </html>
              """;
String query = """
               SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
               WHERE `CITY` = 'INDIANAPOLIS'
               ORDER BY `EMP_ID`, `LAST_NAME`;
               """;


使用该表达式的字符串对象兼容老的表达方式,如两者混合使用,进行相加等操作,调用字符串String的方法等.

String code = String.format("""
              public void print(%s o) {
                  System.out.println(Objects.toString(o));
              }
              """, type);

Stirng新增的有关方法:

String::stripIndent(): 从文本块语法的表达中去除空格.
String::translateEscapes(): 转义退出字符序列.
String::formatted(Object... args): 进行文本块中某些值的格式化.


终于可以不用各种+,各种append了。但是应该会有各种问题,该功能还属于预览版。

 

2.1.2 Switch Expressions

对Switch表达式进行了优化

以前写法

int i;
switch (x) {
    case "1":
        i=1;
        break;
    case "2":
        i=2;
        break;
    default:
        i = x.length();
        break;
}


现在支持

String formatted = 
    switch (obj) {
        case Integer i -> String.format("int %d", i)
        case Byte b    -> String.format("byte %d", b);
        case Long l    -> String.format("long %d", l); 
        case Double d  -> String.format("double %f", d); 
        case String s  -> String.format("String %s", s); 
        default        -> obj.toString();
    };
int eval(Node n) {
    switch(n) {
        case IntNode(int i): return i;
        case NegNode(Node n): return -eval(n);
        case AddNode(Node left, Node right): return eval(left) + eval(right);
        case MulNode(Node left, Node right): return eval(left) * eval(right);
        default: throw new IllegalStateException(n);
    };
}


2.2 新的api

2.2.1 java.nio.file.FileSystems

添加了FileSystems.newFileSystem(Path,Map <String,?>)方法


添加了三种新方法,java.nio.file.FileSystems以使使用文件系统提供程序的文件系统提供程序更容易使用。

newFileSystem(Path)
newFileSystem(Path, Map<String, ?>)
newFileSystem(Path, Map<String, ?>, ClassLoader)


2.2.2 java.nio.ByteBuffer


java.nio.ByteBuffer 新增若干对于buffer的批量的数据get/put,而且不影响buffer位.


java.nio.ByteBufferjava.nio现在,其他缓冲区类型定义了绝对批量get和put方法来传输连续的字节序列,而不考虑或影响缓冲区位置。


2.2.3 dom sax


dom sax解析有关的新api

官方的说法是为初始化dom sax工厂时提供了创建带有默认命名空间的api,特点是方法名上带有NS,三个方法分别是:

newDefaultNSInstance()
newNSInstance()
newNSInstance(String factoryClassName, ClassLoader classLoader)


相应的,使用jdk13,这段代码:

DocumentBuilder db = DocumentBuilderFactory.newDefaultNSInstance().newDocumentBuilder();


等效于:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newDefaultInstance(); 
dbf.setNamespaceAware(true); 
DocumentBuilder db = dbf.newDocumentBuilder();


2.3 unicode12.1 支持


最近每个版本都会扩大字符集支持.


2.4  ZGC取消提交未使用的存储器


ZGC已得到增强,可以将未使用的堆内存返回给操作系统。这对于关注内存占用的应用程序和环境很有用。


默认情况下启用此功能,但可以使用明确禁用此功能-XX:-ZUncommit。此外,不会取消分配内存,以使堆大小缩小到最小堆大小(-Xms)以下。这意味着,如果最小堆大小(-Xms)配置为等于最大堆大小(-Xmx),则将隐式禁用此功能。


可以使用以下命令配置未提交的延迟-XX:ZUncommitDelay=<seconds>(默认为300秒)。此延迟指定在可以取消提交之前应使用多长时间的内存。


注:简单介绍下ZGC,可能我们目前在使用的是CMS垃圾回收器或者是G1垃圾回收器或者什么没有设置使用的是jdk默认的垃圾回收器。


ZGC回收机在jdk11支持,ZGC目前仅适用于Linux / x64 。和G1开启很像,用下面参数即可开启:

-XX:+UnlockExperimentalVMOptions -XX:+UseZGC


ZGC垃圾收集器,也称为ZGC,是一个可扩展的低延迟垃圾收集器,有如下特性:

  • 暂停时间不超过10毫秒
  • 暂停时间不会随堆或实时设置大小而增加
  • 处理堆范围从几百M到几TB。


ZGC的成绩是,无论你开了多大的堆内存(1288G? 2T?),硬是能保证低于10毫秒的JVM停顿,远胜前代的G1。


2.5 添加了-XXSoftMaxHeapSize标志


可管理的命令行标志-XX:SoftMaxHeapSize=<bytes>已添加。当前,它仅在启用Z垃圾收集器(-XX:+UseZGC)时有效。


设置后,GC将努力不使堆增长超出指定的大小,除非GC决定有必要这样做,以避免OutOfMemoryError。不允许将最大软堆大小设置为大于最大堆大小(-Xmx)的值。如果未在命令行上设置,则默认为等于最大堆大小的值。


这个值可以在运行时调整其值。例如,可以通过使用jcmd VM.set_flag SoftMaxHeapSize <bytes>或通过HotSpot MXBean 来调整其值。


在一些特定的场景下我们需要这个新的特性,如非常在意资源使用,希望保持低堆内存占用,但同时又想同时能应付临时的,偶发的内存空间突增,尤其是在并发场景下无法预知的对象分配速率的突增.设置软最大堆内存将鼓励gc维护一个小堆,这样gc会更积极的进行垃圾回收,对于应用程序突发地增加对象分配速度也能更加从容应对.


2.6 ZGC支持的最大堆变化


ZGC支持的最大堆大小从4TB增加到16TB。


2.7 动态CDS归档


CDS的功能在进化一步,就是动态CDS功能。说白了,可以在运行期间动态保存类数据,也就是所谓的归档。


应用程序class-data Sharing(AppCDS)在JDK13新版本里已经简化。在应用程序退出时,可以动态存档类数据。动态生成的归档文件将在与正在运行的JDK映像一起打包的默认系统归档文件上创建生成,并保存数据。

#创建存档文件
% bin/java -XX:ArchiveClassesAtExit=helloworld.jsa -cp helloworld.jar Hello
# 使用存档文件
% bin/java -XX:SharedArchiveFile=hello.jsa -cp helloworld.jar Hello
# 使用动态存档,在老文档基础上
% bin/java -XX:SharedArchiveFile=<base archive>:helloworld.jsa -cp helloworld.jar Hello


2.8 CRL的可配置读取超时


com.sun.security.crl.readtimeout系统属性设置为CRL检索的最大读取超时,单位为秒。如果尚未设置该属性,或者该属性的值为负,则将其设置为默认值15秒。值为0表示无限超时。


2.9 新增TLS配置信息命令


keytool -showinfo -tls添加了显示TLS配置信息的新命令。


2.10 支持下一代MS密码学(CNG)


SunMSCAPI提供程序现在支持读取下一代加密(CNG)格式的私钥。这意味着可以从Windows密钥库(例如“ Windows-MY”)中加载CNG格式的RSA和EC密钥。与EC(签名算法SHA1withECDSASHA256withECDSA等等)也支持。


2.11 SunPKCS11提供升级与PKCS#11 V2.40支持


SunPKCS11提供程序已更新,支持PKCS#11 v2.40。当基础PKCS11库支持相应的PKCS11机制时,此版本增加了对更多算法的支持,例如AES / GCM / NoPadding密码,使用SHA-2消息摘要系列的DSA签名以及RSASSA-PSS签名。


以上为新增功能,部分新增安全相关的功能因为和开发可能没有太大关系,没有介绍。想了解的可以点击官方文档进行查看。


三、删除功能


3.1 删除awt.toolkit系统属性


历史上(直到JDK 1.8),java.awt.Toolkit该类的文档称为“ awt.toolkit”系统属性,该属性设置为平台实现子类的名称。


3.2 删除运行时跟踪方法


过时的方法traceInstructions(boolean),traceMethodCalls(boolean)已经从删除java.lang.Runtime类。这些方法在许多发行版中都无法使用,它们的预期功能由Java虚拟机工具接口(JVMTI)提供。


3.3 不再支持JDK 1.4之前的SocketImpl实现


java.net.SocketImpl在此发行版中已删除了对为Java SE 1.3和更早版本编译的自定义实现的支持。此更改对SocketImpl为Java SE 1.4(2002年发布)或更高版本编译的实现没有影响。


3.4 删除VM选项-XX + AggressiveOpts


-XX:+AggressiveOpts在JDK 11中不建议使用VM选项,在JDK 12中删除了对VM的支持(在该选项中,它的使用被忽略,除了生成警告之外)。现在,使用此标志将导致VM初始化错误。


3.5 重复的RSA服务不再受SunJSSE提供支持


为支持RSA KeyFactoryRSA KeyPairGeneratorMD2withRSAMD5withRSA,和SHA1withRSA Signature已经从SunJSSE提供商删除。


从JDK 5开始,SunRsaSign引入了提供程序来支持这些与RSA相关的算法。SunJSSE提供程序支持这些功能的唯一原因是与JDK 5之前的应用程序向后兼容。删除只会影响明确要求SunJSSE提供者提供这些RSA服务的应用程序。应用程序应删除硬编码的“ SunJSSE”提供程序名称。


3.6 证书删除


因为过期,以下证书被删除删除两个DocuSign根CA证书 , 删除两个Comodo根CA证书,删除T-Systems德国电信根CA 2证书


3.7 删除com.sun.net.ssl软件包


内部软件包com.sun.net.ssl已从JDK中删除。在Java SE 1.4之前,当JSSE作为独立产品交付时,com.sun.net.ssl就支持这些API,但是自Java SE 1.4起,该软件包已被弃用,仅供内部使用。自Java SE 1.4开始,软件包中已提供标准的替代API,如HostNameVerifier,KeyManager和。尽管应用程序应该已经过渡到标准API,但是此注释是最终警告,这些非标准API已被删除。TrustManagerjavax.net.ssl


3.8 FIPS 140兼容模式去除


FIPS 140兼容模式已从SunJSSE提供程序中删除。旧版应用程序可能已通过以下方法之一使用了实验模式:


1.更新java.security文件并为SunJSSE提供程序指定加密提供程序(例如,security.provider.4=com.sun.net.ssl.internal.ssl.Provider SunPKCS11-NSS)


2.使用JDK内部类并使用指定的加密提供程序(例如,new com.sun.net.ssl.internal.ssl.Provider(cryptoProvider);)创建提供程序。


因为SunJSSE提供程序使用JDK默认密码提供程序,所以应用程序可以配置security.provider安全属性以使用符合FIPS 140的密码提供程序。


四、不推荐使用的功能和选项


4.1 StringBuilder和StringBuffer参数为负引发的异常


StringBuilder和StringBuffer参数为负长度数组时抛出NegativeArraySizeException .


4.2 Linux上的默认进程启动机制


linux系统下,进程的默认开启机制使用posix_spawn,这一块需要参考linux创建进程的四种方式,fork(), fork()-exec(), posix_spawn()是异步进程,多进程可以并行执行,和system这种同步方式,多进程不能同时执行.从官方给的链接来看,原来用的似乎是fork/vfork?


4.3 jli包限定使用方法句柄对于静态常量字段的设值权限


即使使用了Field.setAccessibe(true)设置了权限,那么对相应的字段进行java.lang.invoke.MethodHandles.Lookup::unreflectSetter 时,也会抛出IllegalAccessException .在前面java9-12一文中提到过一些关于两个句柄的介绍,作者个人建议了解,个人觉得它们有未来在各框架中大量使用的可能性.


4.4 SocketImpl一些默认实现的变更.


此处影响的三个方法是jdk9才出现的方法,在13中,方法supportedOptions() 的默认返回值会是一个空集,getOption和setOption将默认抛出UnsupportedOperationException,代码中或继承了SocketImpl或DatagramSocketImpl 则必须重写这两个方法.


4.5 NewDirectByteBuffer 开辟的直接内存将固定为大字节序.


以指定该NewDirectByteBuffer函数创建一个始终为big-endian(高字节在前;java.nio.ByteOrder.BIG_ENDIAN)的直接缓冲区。


4.6 Files.isHidden 在windows中使用隐藏目录时返回true.


在Microsoft Windows上,该java.nio.file.Files.isHidden方法历来忽略目录上的DOS“隐藏”属性。此版本已修复此问题,因此,当调用它来测试设置了此属性的目录时,isHidden现在返回true。


4.7 Base64.Encoder和Base64.Decoder方法可以抛出的OutOfMemoryError


对于大型数组,Base64.Encoder.encode和Base64.Decoder.decode方法的行为已更改。这些方法先前引发了未指定的异常,例如NegativeArraySizeException。OutOfMemoryError如果encode和decode方法无法分配输出数组/缓冲区或内存,则新行为将引发异常。


4.8 对于压缩文件(zip或jar)的api进行内容更新时的注意事项


若使用了zip file system去更新其中包含未压缩项的压缩包,则会令损坏该文件,若该包中不包含未压缩的项,则不会有问题.当要对这种含有未压缩条目的压缩包更新时,应使用jar工具或者java.util.zip包下的工具解决.


4.9 对于x86_64无压缩引用的场景,将有更多可用寄存器资源.


在x86_64上有压缩引用的场景下运行时,会消耗一个cpu寄存器去存放base指针,它将用来处理引用的编解码,那么这个寄存器就不能用来分配了.在13之前,即使没用到压缩引用,这个寄存器也是无用了,在本版本,该寄存器会被交还给寄存器池,使用了超大堆和有XX:-UseCompressedOops配置的场景将因此获益.


4.10 提升稀疏prt条目工效.


prt即per region table,与垃圾收集器中的位图有关,在g1中,记忆集的存储便是稀疏prt,官方的简述很好理解,原来prt中能存放的条目是随着region的增大而线性增长的,现在变为指数增长.


这意味着G1对于 1/2/4/8/16/32 MB 的region将能每prt分别使用 4/8/16/32/62/128 个条目,以前则分别是每prt使用4/8/12/16/20/24 条目.


4.11 jrt协议只能编码jrt:/modules树下的路径.


前面说过,从jdk9开始,官方提供了一个新的url pattern jrt,并使用jrt:/module/resource具体定位一个资源(类或配置等).在/packages树中的文件,使用jrt 文件系统进行toUri操作时,可能会抛出IOError,阻止下一步操作.


五、总结


以上为该版本的新增以及删除的特性。并且引进了新的编码风格。使其我们编码更加清晰。但功能还处于预览阶段。暂时最好不要投入生产环境使用。


JDK13并不是LTS(长期支持)版本,如果你正在使用Java 8(LTS)或者Java 11(LTS),暂时可以不必升级到Java 13.


20191006112434483.png


参考资料:

https://www.oracle.com/technetwork/java/javase/13all-relnotes-5461743.html#Deprecated

https://segmentfault.com/a/1190000020438868?utm_source=tag-newest

目录
相关文章
|
2月前
|
存储 安全 Java
Java Map新玩法:探索HashMap和TreeMap的高级特性,让你的代码更强大!
【10月更文挑战第17天】Java Map新玩法:探索HashMap和TreeMap的高级特性,让你的代码更强大!
78 2
|
2月前
|
存储 Java
深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。
【10月更文挑战第16天】本文深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。HashSet基于哈希表实现,添加元素时根据哈希值分布,遍历时顺序不可预测;而TreeSet利用红黑树结构,按自然顺序或自定义顺序存储元素,确保遍历时有序输出。文章还提供了示例代码,帮助读者更好地理解这两种集合类型的使用场景和内部机制。
46 3
|
2月前
|
存储 Java 数据处理
Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位
【10月更文挑战第16天】Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位。本文通过快速去重和高效查找两个案例,展示了Set如何简化数据处理流程,提升代码效率。使用HashSet可轻松实现数据去重,而contains方法则提供了快速查找的功能,彰显了Set在处理大量数据时的优势。
36 2
|
2月前
|
存储 算法 Java
Java Set因其“无重复”特性在集合框架中独树一帜
【10月更文挑战第14天】Java Set因其“无重复”特性在集合框架中独树一帜。本文深入解析Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定的数据结构(哈希表、红黑树)确保元素唯一性,并提供最佳实践建议,包括选择合适的Set实现类和正确实现自定义对象的`hashCode()`与`equals()`方法。
36 3
|
2月前
|
安全 Java API
Java 17新特性让你的代码起飞!
【10月更文挑战第4天】自Java 8发布以来,Java语言经历了多次重大更新,每一次都引入了令人兴奋的新特性,极大地提升了开发效率和代码质量。本文将带你从Java 8一路走到Java 17,探索那些能让你的代码起飞的关键特性。
93 1
|
2月前
|
编解码 Oracle Java
java9到java17的新特性学习--github新项目
本文宣布了一个名为"JavaLearnNote"的新GitHub项目,该项目旨在帮助Java开发者深入理解和掌握从Java 9到Java 17的每个版本的关键新特性,并通过实战演示、社区支持和持续更新来促进学习。
90 3
|
10天前
|
存储 Java 开发者
什么是java的Compact Strings特性,什么情况下使用
Java 9引入了紧凑字符串特性,优化了字符串的内存使用。它通过将字符串从UTF-16字符数组改为字节数组存储,根据内容选择更节省内存的编码方式,通常能节省10%至15%的内存。
|
19天前
|
存储 Java 数据挖掘
Java 8 新特性之 Stream API:函数式编程风格的数据处理范式
Java 8 引入的 Stream API 提供了一种新的数据处理方式,支持函数式编程风格,能够高效、简洁地处理集合数据,实现过滤、映射、聚合等操作。
35 6
|
1月前
|
分布式计算 Java API
Java 8引入了流处理和函数式编程两大新特性
Java 8引入了流处理和函数式编程两大新特性。流处理提供了一种声明式的数据处理方式,使代码更简洁易读;函数式编程通过Lambda表达式和函数式接口,简化了代码书写,提高了灵活性。此外,Java 8还引入了Optional类、新的日期时间API等,进一步增强了编程能力。这些新特性使开发者能够编写更高效、更清晰的代码。
33 4
|
2月前
|
存储 Java API
优雅地使用Java Map,通过掌握其高级特性和技巧,让代码更简洁。
【10月更文挑战第19天】本文介绍了如何优雅地使用Java Map,通过掌握其高级特性和技巧,让代码更简洁。内容包括Map的初始化、使用Stream API处理Map、利用merge方法、使用ComputeIfAbsent和ComputeIfPresent,以及Map的默认方法。这些技巧不仅提高了代码的可读性和维护性,还提升了开发效率。
95 3