JDK9特性——语法、API的改变

淩亂°似流年 2023-10-16 00:21 78阅读 0赞

文章目录

  • 语法层次改变
    • 钻石操作符号语法升级
    • try结构语法升级
    • 下划线命名标识符的使用限制
  • API层次的改变
    • 接口中的私有方法
    • String底层存储结构变化
    • Stream新增4个API
    • InputStream新增transferTo方法
    • 只读集合创建

语法层次改变

钻石操作符号语法升级

钻石操作符,就是我们泛型使用的符号<>

JAVA8 中,匿名内部类不能使用钻石操作符,如下代码在JAVA8 中是报错的,匿名内部类这里不支持泛型推断,重写的方法不明确泛型

在这里插入图片描述

这里匿名内部类中的<>号里必须要和前面的声明保持一致,不能空着不写,这样重写的方法就根据匿名内部类的泛型

在这里插入图片描述

但是这种写法在JAVA9 中就允许了

image.png

而且在JAVA9中,匿名内部类的语法不仅仅可以用于接口和抽象类,普通类也可以通过匿名内部类写法,在某个实例上完成对某个方法的重写

  1. public class Demo1 {
  2. public static void main(String[] args) {
  3. /*
  4. * 匿名内部类仅仅在接口和抽象类上使用,作为一种快速的实现方式
  5. * JAVA9中,普通类也可以借助这种语法形式实现对方法的快速临时的重写
  6. * */
  7. Person<String> person=new Person<>(){
  8. @Override
  9. public void eat(String s) {
  10. super.eat(s);
  11. }
  12. };
  13. person.eat("油条");
  14. }
  15. }
  16. class Person<T>{
  17. public void eat(T t){
  18. System.out.println("Person eat");
  19. }
  20. }

try结构语法升级

普通的try catch finally语句 ,要释放的资源可以放到finally语句块中

  1. public class Demo02 {
  2. public static void main(String[] args) {
  3. InputStreamReader reader =null;
  4. try{
  5. reader =new InputStreamReader(System.in);
  6. int read = reader.read();
  7. }catch (Exception e){
  8. throw new RuntimeException(e);
  9. }finally {
  10. // 这里可以释放资源
  11. if(null != reader){
  12. try {
  13. reader.close();
  14. } catch (IOException e) {
  15. e.printStackTrace();
  16. }
  17. }
  18. }
  19. }
  20. }

JAVA 8中已经对try语法进行了升级,可以将要释放的资源放到try后面的小括号中,这样就不用通过finally语句块释放资源了,但是要求执行后必须关闭的资源一定要放在try子句中进行初始化,否则编译不通过. 下面的案例中,reader必须放在try后面的小括号中进行初始化

  1. public static void main(String[] args) {
  2. try( InputStreamReader reader=new InputStreamReader(System.in) ){
  3. int read = reader.read();
  4. }catch (Exception e){
  5. throw new RuntimeException(e);
  6. }
  7. }

JAVA 9 资源的关闭操作,可以在try子句中使用已经初始化的资源但是此时的资源必须是final修饰的,final可以省略不写

  1. // JAVA9 try语法升级
  2. public void testb() throws FileNotFoundException {
  3. // JAVA9 try catch finally语句块
  4. InputStreamReader isr =new InputStreamReader(new FileInputStream("d:/UserMapper.xml"));
  5. OutputStreamWriter isw =new OutputStreamWriter(new FileOutputStream("d:/UserMapper1.xml"));
  6. try( isr; isw){
  7. isr.read();
  8. }catch (Exception e){
  9. e.printStackTrace();
  10. }
  11. }

下划线命名标识符的使用限制

标识符命名组成:字母,数字,下划线,$

JAVA8 中,可以使用一个 _ 作为标识符的命名

image.png

JAVA9 中,就不可以使用一个 _ 作为标识符的命名了,但是标识符中仍然可以使用_,必须配合其他内容

在这里插入图片描述

API层次的改变

接口中的私有方法

接口中的设计使用在JDK7、8、9中都有相关的变化的。

JAVA7 中,接口只能有抽象方法

JAVA8 中,接口中static(静态不可重写)和default(可以重写)修饰的方法可以拥有方法体

JAVA9 中,接口中可以使用private修饰方法,并拥有方法体,但是接口中的成员变量仍然不能用private修饰

image.png

代码案例

  1. public class Demo4 {
  2. // 接口,是一种规范和要求
  3. // 实现多继承
  4. }
  5. // java7 接口中的方法必须都是抽象的
  6. interface Inter1 {
  7. void methoda();
  8. }
  9. // java8接口可以定义static/default修饰的非抽象方法
  10. interface Inter2 {
  11. void methoda();
  12. static void methodB() {
  13. }
  14. default void methodC() {
  15. }
  16. }
  17. // java9 允许定义私有的非抽象方法
  18. interface Inter3 {
  19. void methoda();
  20. static void methodB() {
  21. }
  22. default void methodC() {
  23. methodD();
  24. }
  25. private void methodD() {
  26. }
  27. }

String底层存储结构变化

JAVA8 中String类内部维护的是一个final修饰的私有char数组,说明String的底层是通过char数组存储字符串的。

image.png

JAVA9 中String的源码,String类内部维护的是一个final修饰的私有byte数组,说明String的底层是通过byte数组存储字符串的.

image.png

这么调整的原因:

在Java 9之前,如果要在代码中表示二进制数据,需要手动将二进制数据转换为字节数组,然后使用字节数组来创建String对象。这个过程比较繁琐,并且容易出错。

为了简化这个过程,Java 9引入了二进制字符串字面值。现在,可以直接在代码中使用前缀0b来表示二进制数据,并将其转换为String对象。例如:

  1. String binaryString = "0b101010";

Stream新增4个API

JAVA9 中,Stream接口添加了4个新方法,takeWhile、dropWhile、ofNullable以及 iterate。

takeWhile是从流中的头开始取元素,直到不满足条件为止。

  1. public static void testTakeWhile(){
  2. List<Integer> list = Arrays.asList(1, 89, 63, 45, 72, 65, 41, 65, 82, 35, 95, 100);
  3. // 从头开始取所有奇数,直到遇见一个偶数为止
  4. list.stream().takeWhile(e-> e%2==1).forEach(System.out::println);
  5. }

dropWhile 从头开始删除满足条件的数据,直到遇见第一个不满足的位置,并保留剩余元素

  1. public static void testDropWhile(){
  2. List<Integer> list = Arrays.asList(2, 86, 63, 45, 72, 65, 41, 65, 82, 35, 95, 100);
  3. // 删除流开头所有的偶数,直到遇见奇数为止
  4. list.stream().dropWhile(e-> e%2==0 ).forEach(System.out::println);
  5. }

ofNullable 允许创建Stream流时只放入一个null

  1. public static void testOfNullable(){
  2. // of方法获取流 ,允许元素中有多个null值
  3. Stream<Integer> stream1 = Stream.of(10, 20, 30, null);
  4. // 如果元素中只有一个null,是不允许的
  5. Stream<Integer> stream2 = Stream.of(null);
  6. // JAVA9中,如果元素为null,返回的是一个空Stream,如果不为null,返回一个只有一个元素的Stream
  7. Stream<Integer> stream3 = Stream.ofNullable(null);
  8. }

iterate指定种子数、指定条件和迭代方式来获取流

  1. public static void testNewIterate(){
  2. //JAVA8通过 generate方法获取一个Stream
  3. Stream.generate(Math::random).limit(10).forEach(System.out::println);
  4. //JAVA8 通过iterate获取一个Stream
  5. Stream.iterate(0,t-> t+2).limit(10).forEach(System.out::println);
  6. //JAVA9通过重载iterate获取Stream
  7. Stream.iterate(0,t -> t<10,t-> t+1).forEach(System.out::println);
  8. }

除了Stream本身的扩展,Optional和Stream之间的结合也得到了改进,现在可以通过Optional的新方法将一个Optional对象转换为一个Stream对象(可能是空的)

  1. /**
  2. * Optional类新增Stream方法,可以将一个Optional转换为Stream
  3. */
  4. public static void testOptionalStream(){
  5. List<Integer> list =new ArrayList<>();
  6. Collections.addAll(list,10,5,45,95,36,85,47);
  7. Optional<List<Integer>> optional=Optional.ofNullable(list);
  8. // 通过optional的Stream方法获取一个Stream
  9. Stream<List<Integer>> stream = optional.stream();
  10. // 以为内部的每个元素也是一个List,通过flatMap方法,将内部的List转换为Stream后再放入一个大Stream
  11. stream.flatMap(x->x.stream()).forEach(System.out::println);
  12. }

InputStream新增transferTo方法

InputStream新增transferTo方法,可以用来将数据直接传输到OutpuStream,这是在处理原始数据时非常常见的一种方法

  1. InputStream inputStream =new FileInputStream("d:/aaa.txt");
  2. OutputStream outputStream=new FileOutputStream("d:/bbb.txt");
  3. try (inputStream;outputStream){
  4. inputStream.transferTo(outputStream);
  5. } catch (IOException e) {
  6. e.printStackTrace();
  7. }

只读集合创建

JAVA8 要创建一个只读不可改变的集合,要添加元素再通过unmodifiableList才能让集合变为只读集合。

  1. List<String> list= new ArrayList<>();
  2. list.add("Tom");
  3. list.add("Jerry");
  4. list = Collections.unmodifiableList(list);
  5. System.out.println(list);

JAVA9 通过集合工厂方法,创建一个只读集合,只要通过新增的of方法即可完成创建.

  1. public static void main(String[] args) {
  2. List<String> list = List.of("张三", "李四", "王五");
  3. System.out.println(list);
  4. list.set(0,"aaa");
  5. System.out.println(list);
  6. }

image.png

同样的Set接口和Map接口下也新增了of方法,也是返回一个只读集合

发表评论

表情:
评论列表 (有 0 条评论,78人围观)

还没有评论,来说两句吧...

相关阅读

    相关 jdk9特性

    Java 9 新特性 Java 9 发布于 2017 年 9 月 22 日,带来了很多新特性,其中最主要的变化是已经实现的模块化系统。接下来我们会详细介绍 Java 9

    相关 JDK9特性2

    1 Java平台模块化系统 该特性是Java 9 最大的一个特性,Java 9起初的代号就叫Jigsaw,最近被更改为Modularity,Modularity提供了类似

    相关 JDk9特性

    (一):jdk和jre的改变   JDK和JRE已经在Java SE 9中进行了模块化处理。在Java SE 9之前,JDK构建系统用于生成两种类型的运行时映像 ——Jav