当前位置:   article > 正文

JDK不同版本间的新特性-进阶篇_jdk171819

jdk171819

目录

 

一、介绍 

1.1 介绍

二、JDK9-15新特性

2.1 JDK9新特性——模块化特性

2.2 JDK11新特性——HTTP2 与HttpClient

HTTP/2关键特性:

代码演示: 

2.3 JDK15新特性——隐藏类

隐藏类的作用:

代码对比: 

三、JDK16-18新特性

3.1 JDK16新特性——Records档案类

3.2 JDK17新特性——密封类

3.3 JDK18新特性——默认UTF-8字符集

3.4 总结


一、介绍 

1.1 介绍

        1. JDK9: 模块化特性

        2. JDK11: HTTP/2与HttpClient

        3. JDK15: 隐藏类

        4. JDK16: Records档案类

        5. JDK17: 密封类

        6. JDK18: 默认UTF-8编码

强调说明:

        基础篇主要讲解JDK新版本新语法特性,版本号以首次提出时间(Preview)为准。

       进阶篇主要讲解JDK新版本新机制,为保证应用稳定性,版本号以正式发布版本为准。

二、JDK9-15新特性

2.1 JDK9新特性——模块化特性

        Java程序被拆分成N个模块,并允许Java程序可以根据需要选择只加载程序必要的Java模块,这样就可以让Java以轻量化的方式来运行。

        模块是一个比“包”更大的程序单元,一个模块可以包含多个包,而每个包下又可包含N个Java类型。

        模块会新增一个叫module-info.java,描述当前模块对外要暴露哪些包,或要去引入其他哪些模块。通过module-info.java,描述模块与模块的依赖关系是什么样的。

  1. //module-info.java代码
  2. module user.service {
  3. exports com.imooc.user.service;
  4. exports com.imooc.user.entity;
  5. requires db.service;
  6. }

        模块与模块之间的关系,实际上是由IDEA管理的。new modules、编译之后,形成彼此依赖,由IDEA保存在每一个模块下的 xxx.iml 文件中的<orderEntry>标签,标识引用的模块。通过描述文件的形式,IDEA就知道在B模块编译时,B模块依赖了A模块对外暴露的包。

        xxx.iml:IDEA自己的工程描述文件。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <module type="JAVA_MODULE" version="4">
  3. <component name="NewModuleRootManager" inherit-compiler-output="true">
  4. <exclude-output />
  5. <content url="file://$MODULE_DIR$">
  6. <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
  7. </content>
  8. <orderEntry type="inheritedJdk" />
  9. <orderEntry type="sourceFolder" forTests="false" />
  10. <orderEntry type="module" module-name="db-service" />
  11. </component>
  12. </module>

编译打包之后的文件结构:

  

        主要用途:将我们原始的一个大工程,按照模块的方式拆解成多个小模块。而这个小模块每个都是可以独立维护的目录,你可以把它认为是个子工程,不同的团队维护属于自己的模块,这样分工合作大家都轻松。

2.2 JDK11新特性——HTTP2 与HttpClient

全新的HttpClient可以提供的功能选项:

        完整支持HTTP2.0

        支持HTTPS/TLS

        阻塞同步通信

        非阻塞异步通信

        支持WebSocket

        支持响应式流

HTTP/2关键特性:

        二进制分帧(HTTP1.1中请求头基于文本形式传输、一个线程对应一个链接 会阻塞。HTTP/2以二进制的形式传输)

        首部压缩(请求帧会缓存在服务器中,再次有大部分内容相同的请求时,只发送变动的部分就可以了)

        流量控制

        多路复用(HTTP/2中客户端会和服务端建立稳定的通信管道)

        请求优先级

        服务器推送

代码演示: 

  1. package com.imooc.httpclient;
  2. import java.net.URI;
  3. import java.net.http.HttpClient;
  4. import java.net.http.HttpRequest;
  5. import java.net.http.HttpResponse;
  6. import java.util.concurrent.CompletableFuture;
  7. import java.util.concurrent.ExecutionException;
  8. import java.util.concurrent.TimeUnit;
  9. import java.util.concurrent.TimeoutException;
  10. public class HttpClientSample {
  11. public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
  12. //1.实例化HttpClient客户端
  13. HttpClient client = HttpClient.newBuilder().version(HttpClient.Version.HTTP_2).build().newHttpClient();
  14. //2.构建请求对象
  15. HttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://www.imooc.com")).GET().build();
  16. //3.发送请求,处理响应
  17. CompletableFuture<HttpResponse<String>> asyncResponse = client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
  18. String body = asyncResponse.thenApply(response -> response.body()).get(5, TimeUnit.SECONDS);
  19. System.out.println(body);
  20. }
  21. }

注释:

        macos底层字符集为UTF-8。

        JDK18版本下,windows系统IDEA控制台 中文会乱码。

        Modify options -> Add VM options -> vm options: -Dfile.encoding-gbk

        控制台输出时采用gbk编码,和Windows系统默认字符集保持一致。就能正常显示了。

2.3 JDK15新特性——隐藏类

        Hidden Classes就是不能直接被其他class的二进制代码使用的class。Hidden Classes主要被一些框架用来生成运行时类,但是这些类不是被用来直接使用的,而是通过反射机制来调用。 

        在JDK8中引入的lambda表达式,JVM并不会在编译的时候将lambda表达式转换成为专门的类,而是在运行时将相应的字节码动态生成相应的类对象。

隐藏类的作用:

        隐藏类天生为框架设计的,在运行时生成内部的class

        隐藏类只能通过反射访问,不能直接被其他类的字节码访问

        隐藏类可以独立于其他类加载、卸载,这可以减少框架的内存占用

        解释:用spring在运行时生成1000个动态类,这1000个动态类当被生成以后,按照以前的机制,会一直驻留在内存当中,会占用更多内存,让jvm执行效率变得低下。在隐藏类出现之后,这些隐藏类用完之后马上卸载掉,这样减少内存占用、提高程序执行效率。 

代码对比: 

        实现类通过字节码的形式保存在磁盘上。静态字节码文件产生之后,一旦被加载,按照JVM的逻辑,它就一直存在一直占用内存。

  1. package com.imooc.jdk15;
  2. public class HiddenClassesSample1 {
  3. public static void main(String[] args) {
  4. Runnable runnable = new Runnable() {
  5. @Override
  6. public void run() {
  7. System.out.println("Runnable");
  8. }
  9. };
  10. }
  11. }

        动态实现类 用完就抛弃掉。JAVA15中会把lambda表达式作为隐藏类处理。

  1. package com.imooc.jdk15;
  2. public class HiddenClassesSample2 {
  3. public static void main(String[] args) {
  4. Runnable runnable = ()->System.out.println("Runnable");
  5. }
  6. }

        Spring框架使用JAVA15隐藏类特性做了升级。

        defineHiddenClass方法

三、JDK16-18新特性

3.1 JDK16新特性——Records档案类

        开发人员想要创建纯数据载体类(plain data carriers)通常都必须编写大量低价值、重复的、容易出错的代码。如:构造函数、getter/setter、equals()、hashCode()以及toString()等。

        Records的目标是扩展Java语言语法,Records为声明类提供了一种紧凑的语法,通过对类做这样的声明,编译器可以通过自动创建所有方法并让所有字段参与hashCode()等方法实现。

        Records类使用有些限制,主流应用场景下还没有被铺开。

代码演示: 

  1. package com.imooc.jdk16;
  2. import java.util.ArrayList;
  3. public record User(String username , String password , Integer age , User parent){
  4. /*
  5. 1.record类不允许使用abstract关键字定义为抽象
  6. 2.所有成员变量均为final修饰,不允许再次赋值
  7. 3.不允许实现成员变量
  8. private Float height;
  9. 4.允许出现静态变量/实例方法/静态方法
  10. 5.允许出现其他构造方法,但必须调用record构造方法
  11. 6.record不允许extends继承其他类
  12. */
  13. public User(String username , String password , Integer age){
  14. this(username, password, age, null);
  15. }
  16. private static String desc;
  17. public void showInfo(){
  18. }
  19. }
  1. package com.imooc.jdk16;
  2. public class App {
  3. public static void main(String[] args) {
  4. User user = new User("zhangsan","123456",18,null);
  5. System.out.println(user.username());
  6. System.out.println(user.password());
  7. System.out.println(user.toString());
  8. }
  9. }

3.2 JDK17新特性——密封类

        Sealed Classes密封类的目的是为了限制子类的过度使用,父类的开发者必须声明哪些子类可以继承该父类,以确保不会出现未限定的子类继承父类,导致程序出现意料之外的问题。

public sealed class Job permits Developer, Manager, Salesman {}
  1. package com.imooc.jdk17;
  2. public sealed class Job permits Developer, Manager,Salesman{
  3. }
  4. package com.imooc.jdk17;
  5. import com.imooc.jdk17.Job;
  6. public final class Manager extends Job {
  7. }
  8. package com.imooc.jdk17;
  9. public final class Salesman extends Job{
  10. }
  11. package com.imooc.jdk17;
  12. public sealed class Developer extends Job permits UIDeveloper,WebDeveloper{
  13. }
  14. package com.imooc.jdk17;
  15. public non-sealed class UIDeveloper extends Developer{
  16. }
  17. package com.imooc.jdk17;
  18. public non-sealed class WebDeveloper extends Developer{
  19. }

3.3 JDK18新特性——默认UTF-8字符集

        指定UTF-8作为标准Java API的默认字符集。通过此更改,依赖于字符集的API将在所有实现、操作系统、区域设置和配置中有一致的行为。 

        文件本身有字符集、传输的数据格式有字符集、操作系统有本地字符集。这几者每一个发生变化,一旦不一致就会产生乱码。

        macOS本地字符集为UTF-8。

        Windows英文状态下本地字符集为en-US;中文状态下为GBK;日文状态下为ja-JP。

        JDK18中明确出来,默认Java程序使用强制地UTF-8编码,这样便可以给程序员一个完整的预期。无论是怎样的输入,还是怎样的输出,只要是通过Java程序所产生的,那就是UTF-8编码。通过这种形式,让我们程序员开发的时候有一个稳定的预期和标准的字符集。这便是用意所在。

        JDK18之前,Java程序的字符集基于操作系统的字符集,IDEA控制台也是基于操作系统的字符集。JDK18后,Java程序的字符集是UTF-8,所以Windows下IDEA控制台会乱码。

        设置 -> 编辑器 -> 控制台 -> 默认编码 改为UTF-8,也可以解决Windows下IDEA控制台乱码问题。

3.4 总结

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/53865?site
推荐阅读
相关标签
  

闽ICP备14008679号