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

目录

 

一、介绍 

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,描述模块与模块的依赖关系是什么样的。

//module-info.java代码
module user.service {
    exports com.imooc.user.service;
    exports com.imooc.user.entity;
    requires db.service;
}

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

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

<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
  <component name="NewModuleRootManager" inherit-compiler-output="true">
    <exclude-output />
    <content url="file://$MODULE_DIR$">
      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
    </content>
    <orderEntry type="inheritedJdk" />
    <orderEntry type="sourceFolder" forTests="false" />
    <orderEntry type="module" module-name="db-service" />
  </component>
</module>

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

  

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

2.2 JDK11新特性——HTTP2 与HttpClient

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

        完整支持HTTP2.0

        支持HTTPS/TLS

        阻塞同步通信

        非阻塞异步通信

        支持WebSocket

        支持响应式流

HTTP/2关键特性:

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

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

        流量控制

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

        请求优先级

        服务器推送

代码演示: 

package com.imooc.httpclient;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class HttpClientSample {
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        //1.实例化HttpClient客户端
        HttpClient client = HttpClient.newBuilder().version(HttpClient.Version.HTTP_2).build().newHttpClient();
        //2.构建请求对象
        HttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://www.imooc.com")).GET().build();
        //3.发送请求,处理响应
        CompletableFuture<HttpResponse<String>> asyncResponse = client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
        String body = asyncResponse.thenApply(response -> response.body()).get(5, TimeUnit.SECONDS);
        System.out.println(body);
    }
}

注释:

        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的逻辑,它就一直存在一直占用内存。

package com.imooc.jdk15;

public class HiddenClassesSample1 {
    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("Runnable");
            }
        };
    }
}

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

package com.imooc.jdk15;

public class HiddenClassesSample2 {
    public static void main(String[] args) {
        Runnable runnable = ()->System.out.println("Runnable");
    }
}

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

        defineHiddenClass方法

三、JDK16-18新特性

3.1 JDK16新特性——Records档案类

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

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

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

代码演示: 

package com.imooc.jdk16;

import java.util.ArrayList;

public  record User(String username , String password , Integer age , User parent){

     /*
        1.record类不允许使用abstract关键字定义为抽象
        2.所有成员变量均为final修饰,不允许再次赋值
        3.不允许实现成员变量
        private Float height;
        4.允许出现静态变量/实例方法/静态方法
        5.允许出现其他构造方法,但必须调用record构造方法
        6.record不允许extends继承其他类
    */
    public User(String username , String password , Integer age){
        this(username, password, age, null);
    }
    private static String desc;
    public void showInfo(){

    }
}
package com.imooc.jdk16;

public class App {
    public static void main(String[] args) {
        User user = new User("zhangsan","123456",18,null);
        System.out.println(user.username());
        System.out.println(user.password());
        System.out.println(user.toString());
    }
}

3.2 JDK17新特性——密封类

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

public sealed class Job permits Developer, Manager, Salesman {}
package com.imooc.jdk17;

public sealed class Job permits Developer, Manager,Salesman{
}


package com.imooc.jdk17;

import com.imooc.jdk17.Job;

public final class Manager extends Job {
}


package com.imooc.jdk17;

public final class Salesman extends Job{
}


package com.imooc.jdk17;

public sealed class Developer extends Job permits UIDeveloper,WebDeveloper{
}


package com.imooc.jdk17;

public non-sealed class UIDeveloper extends Developer{
}


package com.imooc.jdk17;

public non-sealed class  WebDeveloper  extends Developer{
}

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 总结

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chengbo_eva

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值