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

语法层次改变

钻石操作符号语法升级

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

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方法,也是返回一个只读集合

猜你喜欢

转载自blog.csdn.net/qq_28314431/article/details/132915873
今日推荐