JDK9-JDK17新特性(重点)

jdk8(2014 年 3 月 18 日发布的)至今,已经将近十年时间,是长期稳定的,但是由于现在springboot3的发布,已经强制需要使用JDK17。

JDK 9 新特性

模块机制(module-info.java)

我们在使用JDK8的时候,当导入一个jar包后,会引入很多的依赖,而我们会使用到的则仅仅是一小部分,通过模块化机制可定制化使用到的jar包,提高jar的利用率
image.png

// 声明模块
module DemoName {
    
    

    // 声明依赖模块, transitive修饰符会导致依赖于当前模块的其他模块具有隐式依赖性。
    requires transitive java.logging;
    requires transitive java.transaction.xa;
    requires transitive java.xml;

    // 声明哪些包是可以被其它模块访问
    exports demo1;
    exports demo2;

    // 使用语句(uses statement)和提供语句(provides statement)实现其服务
    // 使用语句可以指定服务接口的名字,当前模块就会发现它,使用 java.util.ServiceLoader类进行加载
    uses demo.Driver;
}

JDK1.8-jre有200MJDK17-jmods有70M

优势:

  • 让Java SE程序更加容易轻量级部署。
  • 强大的封装能力。
  • 改进组件间的依赖管理,引入比jar粒度更大的Module。
  • 改进性能和安全性。

新增Stream API & 集合工厂方法

JDK 9 为 Stream 新增了几个方法:dropWhile、takeWhile、ofNullable,为 iterate 方法新增了一个重载方法。

takeWhile

Stream
.iterate(0, i -> i < 20, i -> i + 1)  // 可以直接指定 i < 20
.takeWhile(i -> i < 10)  //当i小于10时正常通过,一旦大于等于10直接截断
//.dropWhile(i -> i < 10)   // 和上面的相反, 直接丢弃满足条件的.
.forEach(System.out::println);

dropWhile

Stream
.iterate(0, i -> i < 20, i -> i + 1)  // 可以直接指定 i < 20
//.takeWhile(i -> i < 10)  //当i小于10时正常通过,一旦大于等于10直接截断
.dropWhile(i -> i < 10)   // 和上面的相反, 直接丢弃满足条件的.
.forEach(System.out::println);

ofNullable

Stream
.of(null) //如果传入null会报错
.forEach(System.out::println);

//使用新增的ofNullable方法,这样就不会了,不过这样的话流里面就没东西了
Stream
.ofNullable(null) 
.forEach(System.out::println);

集合工厂方法(不可变)

// 通过java.util.Set 创建 不可变 的集合实例
Set<String> set = Set.of("A", "B", "C");
// 通过java.util.List 创建 不可变 的集合实例
List<String> list = List.of("A", "B", "C");
// 通过k1,v1,k2,v2,...,形式创建
Map<String, String> map = Map.of("A","V1","B","v2","C","v3");
// 通过 Map.entry 形式创建
Map<Integer, String> map1 = Map.ofEntries (
    Map.entry(1, "v1"),
    Map.entry(2, "v2"),
    Map.entry(3, "v3"));

改进版 Try-With Resources

try-with-resources 是 JDK 7 中一个新的异常处理机制,它能够很容易地关闭在 try-catch 语句块中使用的资源。try-with-resources 声明在 JDK 9 已得到改进。如果你已经有一个资源是 final 或等效于 final 变量,您可以在 try-with-resources 语句中使用该变量,而无需在 try-with-resources 语句中声明一个新变量。

static String readData(String message) throws IOException {
    
    
      Reader reader = new StringReader(message);
BufferedReader br = new BufferedReader(reader);
     // 不需要重新声明变量
      try (br) {
    
    
         return br.readLine();
      }
  }

Java 10 新特性

局部变量类型推断

    public static void main(String[] args) {
    
    
    	// String a = "Hello World!";   之前我们定义变量必须指定类型
        var a = "Hello World!";   
        //现在我们使用var关键字来自动进行类型推断,因为完全可以从后面的值来判断是什么类型
    }

Java 11 新特性

用于Lambda的形参局部变量语法

    public static void main(String[] args) {
    
    
        Consumer<String> consumer = (var str) -> {
    
    
 
        };
        Consumer<String> consumer1 = (String str) -> {
    
    
 
        };
//=============================================
  var str = "AB\nC\nD";
    str.lines()   //根据字符串中的\n换行符进行切割,分为多个字符串,并转换为Stream进行操作
        .forEach(System.out::println);

  var str = "ABCD";
    //比如现在我们有一个ABCD,但是现在我们想要一个ABCDABCD这样的基于原本字符串的重复字符串
    System.out.println(str.repeat(2));  //一个repeat就搞定了
String str = " A B C D ";
    System.out.println(str.trim());   //去除首尾空格
    System.out.println(str.strip());   //去除首尾空格
    /**
     * trim()可以去除字符串前后的半角空白字符
     * strip()可以去除字符串前后的全角和半角空白字符
     */
    System.out.println(str.stripLeading());  //去除首部空格
    System.out.println(str.stripTrailing());   //去除尾部空格
    }

全新的HttpClient使用

    public static void main(String[] args) throws URISyntaxException, IOException, InterruptedException {
    
    
 
        HttpClient client = HttpClient.newHttpClient();   //直接创建一个新的HttpClient
        //现在只需要构造一个Http请求实体,就可以让客户端帮助我们发送出去了(实际上就跟浏览器访问类似)
        HttpRequest request = HttpRequest.newBuilder().uri(new URI("https://www.baidu.com")).build();
        //现在就可以把请求发送出去了,注意send方法后面还需要一个响应体处理器(内置了很多)这里我们选择ofString直接吧响应实体转换为String字符串
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        //来看看响应实体是什么吧
        System.out.println(response.body());
    }

Java 12-16 新特性

新的switch语法-Java 14

public static void main(String[] args) {
    
    
        System.out.println(gradeNew(79));
 
    }
 
    public static String gradeNew(int score) {
    
    
        score /= 10;
        return switch (score) {
    
    
            case 10, 9 -> "优秀";
            case 8, 7 -> "良好";
            case 6 -> "及格";
            default -> "不及格";
        };
    }
 
    // yield
    public static String gradeNew2(int score) {
    
    
        score /= 10;
        return switch (score) {
    
    
            case 10, 9 -> "优秀";
            case 8, 7 -> "良好";
            case 6 -> "及格";
            default -> {
    
    
                System.out.println("做了很多事情");
                yield "不及格";
            }
        };
    }

文本块(“”" )-Java 15

不需要转义等多余操作,打印台可直接打印换行字符等

    public static void main(String[] args) {
    
    
        var str = """ 
                dsfds
                sdfsg " > < !
                 dsfdsg dfsdf
                """;
        System.out.println(str);
    }

instanceof语法-Java 16

原先还需要类型各种判断及强制转换
image.png

public class Demo {
    
    
    private String name;
    private int age;

    public boolean equals(Object obj) {
    
    
        if (obj instanceof Demo demo) {
    
    
            return demo.name.equals(this.name);
        }
        return false;
    }
}

Java 17 新特性

密封类型

在Java中,我们可以通过继承(extends关键字)来实现类的能力复用、扩展与增强。但有的时候,可能并不是所有的类我们都希望能够被继承。所以,我们需要对继承关系有一些限制的控制手段,而密封类的作用就是限制类的继承。

实际上在之前我们如果不希望别人继承我们的类,可以直接添加final关键字. 这样有一个缺点,如果添加了final关键字,那么无论是谁,包括我们自己也是没办法实现继承的,但是现在我们有一个需求,只允许我们自己写的类继承A,但是不允许别人写的类继承A,这时该咋写?在Java 17之前想要实现就很麻烦。

    sealed class B permits C,D {
    
    
        // sealed:关键字,表示此类为密封类型
        // permits:后面的类为允许继承的类,双向的
    }
    final class C extends B {
    
    
    
    }
    // non-sealed主动放弃了密封特性:
    non-sealed class D extends B {
    
    
    
    }
//==================================================================================

    sealed class B permits C,D {
    
    
        // sealed:关键字,表示此类为密封类型
        // permits:后面的类为允许继承的类,双向的
    }
    sealed class C extends B {
    
    

    }
    // non-sealed主动放弃了密封特性:
    non-sealed class D extends B {
    
    

    }

    final class CC extends C{
    
    

    }
//=======================================================================================

	// 父
    public sealed [abstract] [class/interface] 类名 [extends 父类] [implements 接口, ...] permits [子类, ...]{
    
    
    		//里面的该咋写咋写
    }
    // 子
    public [final/sealed/non-sealed] class 子类 extends 父类 {
    
       //必须继承自父类
    			//final类型:任何类不能再继承当前类,到此为止,已经封死了。
      		//sealed类型:同父类,需要指定由哪些类继承。
      		//non-sealed类型:重新开放为普通类,任何类都可以继承。
    }
    
    //我们也可以通过反射来获取类是否为密封类型:
    public static void main(String[] args) {
    
    
        Class<B> bClass = B.class;
        Class<C> cClass = C.class;
        Class<D> dClass = D.class;
        System.out.println(bClass.isSealed());   // true
        System.out.println(cClass.isSealed());   // false
        System.out.println(dClass.isSealed());   // false
    }

猜你喜欢

转载自blog.csdn.net/weixin_44824381/article/details/131087029