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

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

@[TOC]

语法层次改变

钻石操作符号语法升级

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

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

在这里插入图片描述

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

在这里插入图片描述

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

image.png

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

public class Demo1 {
   
   
    public static void main(String[] args) {
   
   
        /*
        * 匿名内部类仅仅在接口和抽象类上使用,作为一种快速的实现方式
        * JAVA9中,普通类也可以借助这种语法形式实现对方法的快速临时的重写
        * */
        Person<String> person=new Person<>(){
   
   
            @Override
            public void eat(String s) {
   
   
                super.eat(s);
            }
        };
        person.eat("油条");

    }
}
class Person<T>{
   
   
    public void eat(T t){
   
   
        System.out.println("Person eat");
    }
}

try结构语法升级

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

public class Demo02 {
   
   
    public static void main(String[] args) {
   
   
        InputStreamReader reader =null;
        try{
   
   
            reader =new InputStreamReader(System.in);
            int read = reader.read();
        }catch (Exception e){
   
   
            throw new RuntimeException(e);
        }finally {
   
   
            // 这里可以释放资源
            if(null != reader){
   
   
                try {
   
   
                    reader.close();
                } catch (IOException e) {
   
   
                    e.printStackTrace();
                }
            }
        }
    }
}

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

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

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

    // JAVA9 try语法升级
    public void testb() throws FileNotFoundException {
   
   
        // JAVA9 try catch finally语句块
        InputStreamReader isr =new InputStreamReader(new FileInputStream("d:/UserMapper.xml"));
        OutputStreamWriter isw =new OutputStreamWriter(new FileOutputStream("d:/UserMapper1.xml"));
        try( isr; isw){
   
   
            isr.read();
        }catch (Exception e){
   
   
            e.printStackTrace();
        }
    }

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

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

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

image.png

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

在这里插入图片描述

API层次的改变

接口中的私有方法

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

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

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

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

image.png

代码案例

public class Demo4 {
   
   
    // 接口,是一种规范和要求
    // 实现多继承
}

// java7 接口中的方法必须都是抽象的
interface Inter1 {
   
   
    void methoda();
}

// java8接口可以定义static/default修饰的非抽象方法
interface Inter2 {
   
   
    void methoda();

    static void methodB() {
   
   

    }

    default void methodC() {
   
   

    }
}

// java9 允许定义私有的非抽象方法
interface Inter3 {
   
   
    void methoda();

    static void methodB() {
   
   

    }

    default void methodC() {
   
   
        methodD();
    }

    private void methodD() {
   
   

    }
}

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对象。例如:

String binaryString = "0b101010";

Stream新增4个API

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

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

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

    }

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

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

    }

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

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

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

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

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

    /**
     * Optional类新增Stream方法,可以将一个Optional转换为Stream
     */
    public static void testOptionalStream(){
   
   
        List<Integer> list =new ArrayList<>();
        Collections.addAll(list,10,5,45,95,36,85,47);
        Optional<List<Integer>> optional=Optional.ofNullable(list);

        // 通过optional的Stream方法获取一个Stream
        Stream<List<Integer>> stream = optional.stream();
        // 以为内部的每个元素也是一个List,通过flatMap方法,将内部的List转换为Stream后再放入一个大Stream
        stream.flatMap(x->x.stream()).forEach(System.out::println);

    }

InputStream新增transferTo方法

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

        InputStream inputStream =new FileInputStream("d:/aaa.txt");
        OutputStream outputStream=new FileOutputStream("d:/bbb.txt");
        try (inputStream;outputStream){
   
   
            inputStream.transferTo(outputStream);
        } catch (IOException e) {
   
   
            e.printStackTrace();
        }

只读集合创建

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

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

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

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

image.png

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

相关文章
|
2月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
57 4
|
13天前
|
容器
jdk8新特性-详情查看文档
jdk8新特性-详情查看文档
32 7
|
16天前
|
存储 Java 数据挖掘
Java 8 新特性之 Stream API:函数式编程风格的数据处理范式
Java 8 引入的 Stream API 提供了一种新的数据处理方式,支持函数式编程风格,能够高效、简洁地处理集合数据,实现过滤、映射、聚合等操作。
33 5
|
2月前
|
缓存 JavaScript 前端开发
深入理解 Vue 3 的 Composition API 与新特性
本文详细探讨了 Vue 3 中的 Composition API,包括 setup 函数的使用、响应式数据管理(ref、reactive、toRefs 和 toRef)、侦听器(watch 和 watchEffect)以及计算属性(computed)。我们还介绍了自定义 Hooks 的创建与使用,分析了 Vue 2 与 Vue 3 在响应式系统上的重要区别,并概述了组件生命周期钩子、Fragments、Teleport 和 Suspense 等新特性。通过这些内容,读者将能更深入地理解 Vue 3 的设计理念及其在构建现代前端应用中的优势。
44 1
深入理解 Vue 3 的 Composition API 与新特性
|
1月前
|
JavaScript 前端开发 API
Vue 3新特性详解:Composition API的威力
【10月更文挑战第25天】Vue 3 引入的 Composition API 是一组用于组织和复用组件逻辑的新 API。相比 Options API,它提供了更灵活的结构,便于逻辑复用和代码组织,特别适合复杂组件。本文将探讨 Composition API 的优势,并通过示例代码展示其基本用法,帮助开发者更好地理解和应用这一强大工具。
34 2
|
2月前
|
存储 安全 Java
jdk21的外部函数和内存API(MemorySegment)(官方翻译)
本文介绍了JDK 21中引入的外部函数和内存API(MemorySegment),这些API使得Java程序能够更安全、高效地与JVM外部的代码和数据进行互操作,包括调用外部函数、访问外部内存,以及使用不同的Arena竞技场来分配和管理MemorySegment。
62 1
jdk21的外部函数和内存API(MemorySegment)(官方翻译)
|
3月前
|
存储 JavaScript 前端开发
敲黑板!vue3重点!一文了解Composition API新特性:ref、toRef、toRefs
该文章深入探讨了Vue3中Composition API的关键特性,包括`ref`、`toRef`、`toRefs`的使用方法与场景,以及它们如何帮助开发者更好地管理组件状态和促进逻辑复用。
敲黑板!vue3重点!一文了解Composition API新特性:ref、toRef、toRefs
|
3月前
|
容器
jdk8新特性-详情查看文档
jdk8新特性-详情查看文档
47 3
|
2月前
|
存储 安全 Java
JDK1.8 新的特性
JDK1.8 新的特性
26 0
|
2月前
|
存储 搜索推荐 生物认证
信息搜集:网络空间搜索引擎语法及API的应用(一)
信息搜集:网络空间搜索引擎语法及API的应用(一)
45 0