七:Day01_Java9—16新特性

发布时间:2023年12月31日

第一章 JDK9 新特性

jdk9是新特性最多的,因为jdk8是一个稳定版本。

1、JDK9新特性概述

? ? ? ? 模块系统

(Module System)

Java9最大特性。它提供了类似于OSGI框架的功能,模块之间存在相互的依赖关系,可以导出一个公共的API,并且隐藏实现的细节。作用为减少内存的开销。

? ? ? JShell和Jlink

JShel是交互式Java编程环境。允许开发者在命令行界面中快速编写和测试Java代? 码。

Jlink用于生成自定义的Java运行时映像,可以包含或排除特定的模块。

不可变集合类工厂方法可以更方便地创建不可变集合。
接口中的私有方法接口可以包含私有方法。
try-with-resources改进能够更好地处理异常和资源关闭。
平台日志API和服务提供了新的平台日志API和服务。
垃圾回收器新增了Shenandoah垃圾回收器,旨在提供更高效的垃圾回收。

2 、模块化系统

Java9之前的问题:

1.运行时间长(JVM需要加载rt.jar不管其中的类是否被classloader加载 ,而模块化可以根据? ? ? 模块的需要加载程序运行需要的class)。

2.当代码库越来越大,创建复杂。

3.很难真正地对代码进行封装。

?模块(module)的概念,其实就是package外再裹一层,不声明默认就是隐藏。 模块化使得代码组? 织上更安全,因为它可以指定哪些部分可以暴露,哪些部分隐藏。

模块化做到了:

  • 模块化的主要目的在于减少内存的开销。

  • 只须必要模块,而非全部jdk模块,可简化各种类库和大型应用的开发和维护。

  • 改进 Java SE 平台,使其可以适应不同大小的计算设备。

  • 改进其安全性,可维护性,提高性能。

?jdk9模块化代码:

?? ? ? ?

?注意:导入外部的junit模块并使用,必须将当前模块导出。

3、JShell命令

? ? ? ?基本使用

定义方法,使用方法? ? ? ? ? ? ? ? ?

查看当前Session内代码片段/list
查看当前Session变量/vars
查看当前Session下的方法/methods
使用jshell代码没有受检异常
退出/exit

4 、接口私有方法

public interface demo2 {
    /*
    * jdk8之前接口中只允许有 公有静态常量和抽象方法
    * */
       //接口默认都是公有静态常量,也只能是共有静态常量
        //public static final int num=1;
     int num=1;

    //接口默认方法都是公有抽象方法
      //public abstract void method1();
    void method1();
    /*
     * jdk8及其之后接口可以有静态方法和默认方法
     * */
    public static void method2(){//静态方法
        System.out.println("接口中的静态方法");
    }
    public default void method3(){//默认方法
        System.out.println("接口中的默认方法");
    }
    /*
    * jdk9及其之后接口可以有私有方法
    *     private  void method4(){}
    *     private static void method4(){}
    * 
    * */
    private  void method4(){
        System.out.println("接口中的私有方法");
    }
}

5 、钻石操作符使用升级

在jdk8中,如下代码是报错的

??Comparator<Object> com = new Comparator<>() {
? ? @Override
? ? public int compare(Object o1, Object o2) {
? ? ? ? return 0;
? ? }
};

<>必须写类型。而在jdk9中,上述代码就不报错,这是对<>钻石运算符的一个升级。

6 、try 语句

Java 8 中,可以实现资源的自动关闭,但是要求执行后关闭的所有资源必须在try子句中初始化,否则编译不通过。

?Java 9 中,用资源语句编写try将更容易,我们可以在try子句中使用已经初始化过的资源,此时的资源是final的。

7 、String 存储结构变更

?Jdk9以前

  • 存储在char[ ]中数组,每个字符使用两个字节(16位)。编码为UTF-16。

?Jdk9:?

  • 存储编码为ISO-8859-1/Latin-1(每个字符一个字节byte[] 加上编码标记来存储 )。
  • 或UTF-16(每 个字符两个字节),具体取决于内容字符串的。编码标志将指示使用哪种编码。

?StringBuffer 和 StringBuilder也发生改变。

8、集合特性of()

要创建一个只读、不可改变的集合,必须构造和分配它,然后添加元素,最后包装成一个不可修改的集合。

JAVA 9的方法:
public class demo04 {
    public static void main(String[] args) {

   //jdk9只读集合方法
        List<String> list1=List.of("1","2","3");
        //list1.add("aaa");不支持
        System.out.println(list1);

        Map<String,String> map=Map.of("a","aa","b","bb");
        System.out.println(map);

    }
}

9 、?InputStream增强

jdk8读写数据需要边读边写,jdk9使用TransferTo直接读写进去。

10、增强的的Stream API

  • Java 9 中,Stream 接口中添加了 4 个新的方法:takeWhile, dropWhile, ofNullable, iterate 方法的重载方法,可以提供一个 Predicate (判断条件)来指定什么时候结束迭代。
  • ?可以通过 Optional 的新方法 stream() 将一个 Optional 对象转换为一个(可能是空的) Stream 对象。
public class demo05 {
    public static void main(String[] args) {

        /*
        *     takeWhile() 的使用
        *  用于从 Stream 中获取一部分数据,接收一个 判断条件 来进行选择。
        *  在有序的Stream 中,takeWhile 返回**从开头开始的尽量多的元素。
        *       t ->t<40 遇到第一个不小于40 的元素就停止输出
         * */
        List<Integer> list= Arrays.asList(10,20,30,40,30,20,10);
        list.stream().takeWhile(t ->t<40).forEach(System.out::println);
        List<Integer> list2 = Arrays.asList(1,2,3,4,5,6,7);
        list2.stream().takeWhile(t->t<7).forEach(System.out::println);
        System.out.println("---------------------");
        /*
        *    dropWhile() 的 使用
        *  dropWhile 的行为与 takeWhile 相反,返回剩余的元素
        *      t ->t<40 遇到第一个大于40 的元素就开始输出
        * */
        list.stream().dropWhile(t ->t<30).forEach(System.out::println);
        System.out.println("---------------------");
        /*
        * ofNullable() 的 使用
        *Java 8 中 Stream 不能完全为null,否则会报空指针异常。
        *Java 9 中的 ofNullable 方法允许我们创建一个单元素 Stream,
        *              可以包含一个非空元素,也可以创建一个空Stream。
        * */
        //java 8
           Stream<String> streams = Stream.of("AA","BB",null);//允许通过
          //Stream<Object> stream2 = Stream.of(null);//不允许通过
        //java 9
           Stream<Object> stream3 = Stream.ofNullable(null);//允许通过
        System.out.println("---------------------");
      /*
      *      iterate() 重载的使用
      *  可以让你提供一个 Predicate (判断条件)来指定什么时候结束迭代。
       * */
        //原始方式
        Stream.iterate(1,i->i+1).limit(5).forEach(System.out::println);
        //增强方式
        Stream.iterate(1,i->i<6,i->i+1).forEach(System.out::println);
    }
}

11、Optional 类中stream()使用

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        list.add("赵六");
        Optional<List<String>> optional =Optional.ofNullable(list);
        //optional中只用一个元素 [张三, 李四, 王五, 赵六]
        optional.stream().limit(2).forEach(System.out::println);
        //flatMap(x->x.stream())将一个元素 [张三, 李四, 王五, 赵六],再变为一个一个的元素
        optional.stream().flatMap(x->x.stream()).limit(2).forEach(System.out::println);
        list.stream().limit(2).forEach(System.out::println);
    }
}

第二章 JDK10 新特性

1、局部变量类型推断

在局部变量中使用时,这些情况不适用:初始值为null,方法引用,数组静态初始化,Lambda表达式。

public class demo01 {
    public static void main(String[] args) {
        //1.局部变量的初始化
       var list = new ArrayList<>();
       list.add(1);
       list.add(2);
       list.add(3);
       //2.增强for循环中的索引
        for (var v : list) {
            System.out.println(v);
        }
      // 3.传统for循环中
        for (var i = 0; i <3 ; i++) {
            System.out.println(i);
        }
        /*
        * 在局部变量中使用时,如下情况不适用:
        * */
        //初始值为null
        var a=null;
        //方法引用
        var b=System.out::println;
        //Lambda表达式
        var c=()->Math.random();
        //数组静态初始化
        var arr={"1","2","2"}
         //数组动态初始化可以
        var arr2=new  int[]{1,2,3};
    }
}

注意: ?var 不是一个关键字,不需要担心变量名或方法名会与 var发生冲突。

2、 新增不可变集合方法

jdk9 添加了 of ,jdk10新增copyOf方法,它们两个都用来创建不可变的集合。

不同之处:

public static void main(String[] args) throws Exception {
    //若初始的list1为不可变集合,copyOf之后的List2==list1
        var list1 = List.of("AA","BB","CC");
        var list2 = List.copyOf(list1);
        System.out.println(list1==list2);//true
        //若初始的list3为普通集合,copyOf之后的List2!=list1
        var list3 = new ArrayList<String>();
        list3.add("AA");
        list3.add("BB");
        List<String> list4 = List.copyOf(list3);
        System.out.println(list3==list4); //false
}

copyOf 方 法 会 先 判 断 来 源 集 合 是 不 是AbstractImmutableList 类型的。如果是,就直接返回;如果不是,则调用 of()方法 创建一个新的集合。

第三章 JDK 11新特性

1 、增加ZGC垃圾回收器

  • ZGC, A Scalable Low-Latency Garbage Collector(Experimental)ZGC, 这应该是JDK11最为瞩目的特性, 没有之一。 但是后面带了Experimental,说明这还不建议用到生产环境。

  • ZGC是一个并发, 基于region, 压缩型的垃圾收集器, 只有root扫描阶段会STW(stop the world), 因此GC停顿时间不会随着堆的增长和存活对象的增长而变长。

  • 没有用到生产环境。

2、 Optional加强

以很方便的将一个 Optional 转换成一个 Stream, 或者当一个空 Optional 时给它一个替代。

?

3、新增HTTP客户端API

  • 这是 Java 9 开始引入的一个处理 HTTP 请求的的 HTTP Client API,支持同步和异步,在 Java 11 中为正式可用状态,在java.net 包中。

  • 它将替代仅适用于blocking模式的HttpURLConnection(HttpURLConnection是在HTTP 1.0的时代创建的,并使用了协议无关的方法),并提供对WebSocket 和 HTTP/2的支持。

public static void main(String[] args) throws Exception {
    HttpClient client = HttpClient.newHttpClient();
    HttpRequest request =
        HttpRequest.newBuilder(URI.create("http://www.baidu.com")).build();
    HttpResponse.BodyHandler<String> responseBodyHandler = HttpResponse.BodyHandlers.ofString();
    HttpResponse<String> response = client.send(request, responseBodyHandler);
    String body = response.body();
    System.out.println(body);
}

第四章 JDK 14 新特性

改进的NullPointerExceptions,jdk14以前空指针异常,会指出异常所在处。

jdk14之前空指针异常:

jdk14以后的空指针异常:

第五章 jdk15特性

jdk15提供text block (文本块)功能,解决字符串多行换行问题:


public static void main(String[] args) {
    //jdk15增加文本块
    String str = """
        hello
        world
        hahaha
        """;
        System.out.println(str);
}

第六章 JDK 16 新特性

解决switch语句的一些不规则性成为障碍:

  • 比如case标签之间的默认控制行为

  • case块中的默认范围

  • 无意义的break语句。

但底层还是原始的switch的代码。

public class demo01 {
    public static void main(String[] args) {
        int level = new Random().nextInt(4);
        String str = null;
        switch (level){
            case 1-> str="优秀";
            case 2 -> str="good";
            case 3-> str="yiban";
        }
        System.out.println(str);
       String str2 = switch (level){
           //必须有default
            case 1 -> "haohao";
            case 2-> "good";
           default -> "yiban";
        };
        System.out.println(str2);


        int level2 = new Random().nextInt(12);
        String jiJi = null;
        switch (level2){
            case 3,4,5 -> jiJi="chun";
            case 6,7,8->jiJi="xia";
            case 9,10,11->jiJi="qiu";
            default -> jiJi="dong";
        }
        System.out.println(jiJi);

        String strLeave=switch (level){
            //必须有default
            case 0,1,2->{
                System.out.println("hhh");
                yield "haohaohaoa";
            }
            default -> "jjjjj";
        };
        System.out.println(strLeave);
    }

}

文章来源:https://blog.csdn.net/qq_51318621/article/details/134979984
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。