jdk17新特性

目录

1 语法层面

1.1 文本块

1.2 switch表达式增强

1.3 instanceof的匹配模式

1.4 var局部变量推导

2 模块化以及类封装

2.1 记录类record

2.2 隐藏类Hidden Class

2.3 密封类 Sealed Class

2.4 模块化Module System

2.4.1 什么是模块化

2.4.2 声明一个module

2.4.3 require声明模块依赖

2.4.4 exports和open声明对外的API

2.4.5 uses服务开放机制

2.4.6 构建模块化jar包

2.5 类加载机制调整

2.6 GC调整

2.6.1 ZGC转正

2.6.2 Shenandoah垃圾回收器正式纳入jdk中

2.6.3 废除CMS

2.7 其他调整

3 GraalVM虚拟机

3.1 关于Graal

3.2 安装GraalVM

3.3 使用GraalVM


1 语法层面
1.1 文本块
  • 文本指的多行字符串
  • 使用连续三个引号包围一段多行字符串
  • 避免换行转义麻烦
  • 支持String.format
public class App {
    public static void main(String[] args) {
        String str = """
                this is mutil string
                i name is %s 
                please see it
                """;
        System.out.println(String.format(str,"tom"));
    }
}

1.2 switch表达式增强
  • 支持表达式使用
  • 多条件匹配
public class App {
    public static void main(String[] args) {
      String name = "James1";
      switch (name){
          case "James","libai" -> System.out.println("Hello "+name);
          case "John","qiongsi" -> System.out.println("Hello1 "+name);
          default -> System.out.println("Hello3 "+name);
      }
    }
}

  • 使用yield关键字增加返回值
public class App {
    public static void main(String[] args) {
        String name = "James1";
        int a = switch (name) {
            case "James", "libai" -> {
                System.out.println("Hello " + name);
                yield 1;
            }
            case "John", "qiongsi" -> {
                System.out.println("Hello1 " + name);
                yield 2;
            }
            default -> {
                System.out.println("Hello3 " + name);
                yield 4;
            }
        };
        System.out.println(a);
    }
}

1.3 instanceof的匹配模式
  • 变量类型经过instanceof匹配目标类型可直接声明目标类型变量无需要再次强转
public class App {
    public static void main(String[] args) {
        Object a = "123";
        if (a instanceof Integer i) {
            System.out.println(i.longValue());
        } else if (a instanceof String s) {
            System.out.println(s.charAt(1));
        }
    }
}

1.4 var局部变量推导
  • 对于可以推导其具体类型局部变量可使var修饰
public class App {
    public static void main(String[] args) {
        var s = "123";
        System.out.println(s.charAt(1));
    }
}

2 模块化以及类封装
2.1 记录类record
  • record定义代表不可变常量
  • 只能创建指定属性不能再次修改
public record Person(String name, Integer age) {
    public static void main(String[] args) {
        Person person = new Person("John", 30);
        System.out.println(person);
        System.out.println(person.age());
        System.out.println(person.name());
    }
}

  • 反射也不能修改record属性因为record所有属性上了final修饰

2.2 隐藏类Hidden Class
  • 不能其他直接使用
  • 隐藏不再依赖类加载器
  • 通过读取目标字节方式创建一个其他隐藏class对象
  • 然后通过反射方式创建对象调用方法
public class App {
    private static String encode() throws IOException {
        String classPath="C:\\jwork\\jdk17demo\\target\\classes\\com\\demo\\HiddenClass.class";
        byte[] bytes = Files.readAllBytes(Paths.get(classPath));
        return new String(Base64.getEncoder().encode(bytes));
    }
    public static void main(String[] args) throws Throwable {
        String encode = encode();
        byte[] decode = Base64.getDecoder().decode(encode);
        MethodHandles.Lookup lookup = MethodHandles.lookup().defineHiddenClass(decode,
                true, MethodHandles.Lookup.ClassOption.NESTMATE);
        Class<?> aClass = lookup.lookupClass();

        //获取类名
        System.out.println(aClass.getName());
        //获取所有方法
        for (Method declaredMethod : aClass.getDeclaredMethods()) {
            System.out.println(declaredMethod.getName());
        }
        //调用静态方法
        MethodHandle printHello = lookup.findStatic(aClass, "printHello", MethodType.methodType(void.class, String.class));
        printHello.invokeExact("小明");
        printHello.invoke("小明");
        //创建实例
        MethodHandle newInstance = lookup.findConstructor(aClass, MethodType.methodType(void.class));
        Object invoke = newInstance.invoke();
        System.out.println(invoke);
        //调用实例方法
        MethodHandle sayHello = lookup.findVirtual(aClass, "sayHello", MethodType.methodType(void.class, String.class));
        sayHello.invoke(invoke,"小明");
    }
}

  • 其中加密方式可自由掌控从而达到真实隐藏目的
2.3 密封类 Sealed Class
  • jdk8一个要么可以继承要么不可继承final修饰)
  • jdk17可以指定允许哪些继承
  • sealed表示具有密封必须具有子类通过permits执行允许继承子类
  • non-sealed表示不具备密封性随意集成
  • final表示不能继承
public sealed abstract class Shape permits Circle, Rectangle, Square {
    public abstract int lines();
}
public final class Circle  extends Shape{
    @Override
    public int lines() {
        return 0;
    }
}
public non-sealed class Square  extends Shape{
    @Override
    public int lines() {
        return 0;
    }
}
public sealed class Rectangle extends Shape permits  FilledRectangle{
    @Override
    public int lines() {
        return 0;
    }
}
public final class FilledRectangle extends Rectangle{
}

2.4 模块化Module System
2.4.1 什么是模块化
  • jdk9引入模块机制
  • javapackage上一层抽象
  • 包含一组密切相关包,资源以及一个模块描述文件
  • 通过module可以精准分配对象生效范围

  • jdk8安装目录下,jdk内置功能jar形式存在
  • jdk17安装目录下取而代之一系列jmod文件一个文件代表一个模块

  • jmod文件其实就是一个tar

  • 查看jdk模块列表

2.4.2 声明一个module
  • 模块class目录下创建module-info.java⽂件声明模块
  • 默认情况项目作为模块
  • module-info.java⽂件称之为模块描述文件
  • module-info.java⽂件主要包含如下内容
    • 模块
    • 对其他module依赖关系
    • 当前module对外开放API
    • 使用提供服务
module m2 {
    requires m1;
}

2.4.3 require声明模块依赖
  • require用于声明当前模块需要依赖哪些外部模块
  • 除了pom.xml引入依赖还需要module-info.java添加配置

  • 当前module编译期间需要依赖其他module但是运行期间不需要依赖使用requires static进行依赖声明
2.4.4 exports和open声明对外的API
  • 当需要暴露当前moduleAPI提供外部module使用使用exports声明需要暴漏

  • 通过反射访问外面module私有属性或者方法访问报错

  • 此时需要通过open声明需要暴露可以实现私有属性或者方法访问

2.4.5 uses服务开放机制
  • JDK8SPI机制需要通过配置文件暴露提供服务
  • JDK17重新制定SPI机制
  • 服务提供通过provides ... with ... 暴露服务

  • 服务调用通过uses ... 发现服务

2.4.6 构建模块化jar包
2.5 类加载机制调整
2.6 GC调整
2.6.1 ZGC转正

使用-XX:+useZGC参数启动zgc垃圾回收器

zgc版本升级过程做了很多优化目前查看jdk17中java -XX:+PrintFlagsFinal -version可以看到关于zgc不稳定参数已经基本没有了

2.6.2 Shenandoah垃圾回收器正式纳入jdk中
  • 由RedHat推出Shenandoah垃圾回收器集成jdk
  • 使用参数-XX:+ShenandoahGC启用
2.6.3 废除CMS
  • 随着G1垃圾回收器趋于完善并且后续ZGCshenandoah现代垃圾回收开始登场
  • 过于复杂的并且存在一定问题CMS垃圾回收逐渐淘汰
  • CMS主要问题在于
    • 内存碎片问题
    • Concurrent Mode Fail之后退化Serial垃圾回收器
  • 同时作为CMS备用方案Serial Old垃圾回收器也被废弃
2.7 其他调整
  • 重写socket底层API代码
  • 默认禁用偏向锁通过参数-XX:UseBiasedLocking手动开启

3 GraalVM虚拟机
3.1 关于Graal
  • Graal编译器作为HotSpot C1编译替换方案设计
  • 使用java语言编写
  • 2012Graal编译器发展成为一个一个独立java编译项目
  • 早期Graal需要HotSpot虚拟机配合工作
  • 随着JDK9推出JVMCI(Java虚拟机编译器接口)使得Graal可以HotSpot独立出来并且逐渐形成了现在GraalVM
3.2 安装GraalVM

下载 Download GraalVM

安装与JDK一致

3.3 使用GraalVM
  • GraalVM日常使用jdk基本一致不过重点推出native-image命令
  • native-image命令可以java文件直接编译不需要依赖jdk也可以执行的可执行文件
  • 采用AOT提前编译技术java语言翻译机器码指令从而加快了启动速度以及执行速度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值