• jdk9新特性


    jdk目录结构变化

    image-20210226111223167

    JDK = JRE + 开发工具集(javac编译工具等)

    JRE = JVM + Java SE 标准类库

    jdk8的目录结构:

    image-20210226112026173

    jdk9目录结构:

    image-20210226112236819

    模块化

    先创建两个module

    image-20210226161306893

    image-20210226161323755

    两个普通的java项目(非maven),

    第一个module中创建Person.java

    package com.wj;
    public class Person {
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    

    为module1的模块创建module-info.java

    image-20210226161519803

    并且在module1中的module-info.java

    module module1 {
        exports com.wj;
    }
    

    在module2中导入module1:

    module module2 {
        requires module1;
    }
    

    编写代码的时候,导入进来:

    image-20210226162231058

    编写代码的时候,需要哪些module就导入哪些module就行了。

    REPL工具:jShell命令

    像Python和Scala之类的语言早就有交互式编程环境(REPL)了,以交互式的方式对语句和表达式进行求值。开发者只需要输入一些代码,就可以在编译前获得对程序的反馈。而java9以前的版本想要执行代码,必须创建文件、声明类、提供测试方法才可实现。

    命令行输入:jshell

    image-20210226163241492

    执行代码:

    System.out.println("hello world")
    

    image-20210226163528385

    定义变量:

    int i = 1;
    int j = 2;
    int m = i+j;
    System.out.println(m);
    

    image-20210226163654854

    包括语句中的错误提示也比较详细

    定义方法:

    image-20210226163917349

    还可以修改方法,重新键入add方法

    image-20210226164104213

    导包

    默认情况下,jdk9帮我们默认导入了部分包

    /imports
    

    image-20210226164409113

    例如创建一个ArrayList,不需要导包。

    image-20210226164507231

    如果不在默认的导入包中:

    例如我使用java.time.Year类中的方法:

    我们需要导入 import java.time.Year后,才可以使用。

    image-20210226164754180

    tab补全

    按住tab键可以自动补全类名或者方法,也可以代码提示

    image-20210226164954134

    /list

    列举之前我们键入的指令和操作

    image-20210226165109694

    /vars

    列举之前定义的变量

    image-20210226165144038

    /methods

    列举之前定义的方法

    image-20210226165220386

    /edit

    可以编辑我们定义的方法,弹出编辑框,可以对方法进行修改

    /edit add
    

    image-20210226173455167

    直接输入/edit,可以修改我们之前输入的所有变量和方法

    /open

    可以从外部加载源代码

    我在E盘下写了一个java文件

    image-20210226165803854

    在jshell中直接执行该代码

    /open E:Hello.java
    

    image-20210226165841318

    隐藏受检异常

    部分代码会直接抛出异常,我们在java文件中需要手动捕获,而在jshell中则不用

    image-20210226170316907

    image-20210226170301457

    /exit

    退出jshell

    image-20210226170346627

    接口的私有方法

    jdk9后可以在接口中定义私有方法

    public interface MyInterface {
    
        //抽象方法
        void method1();
    
        //默认方法
        public default void method2(){
    
        }
    
        //静态方法
        public static void method3(){
            System.out.println("method3");
            method4();
        }
    
        //私有方法
        private static void method4(){
            System.out.println("method4");
        }
    }
    
    public class Test {
        public static void main(String[] args) {
            MyInterface.method3();
        }
    }
    

    image-20210226172615082

    钻石操作符升级

    image-20210226173113322

    在jdk8中使用该写法(声明一个HashSet的匿名子类),无法通过编译,在jdk9中则被允许。

    image-20210226173332809

    异常处理升级

    在jdk9以前,我们可以有如下写法

            try(InputStreamReader isr = new InputStreamReader(System.in)){
    
            }catch (IOException e) {
    
    
            }
    

    资源的声明和初始化必须在try的括号中进行,然后才可以自动关闭资源,

    在jdk9以后,我们可以先声明资源,在写入括号中:

            InputStreamReader isr = new InputStreamReader(System.in);
            try (isr){
    
            } catch (IOException e) {
    
            }
    

    注意:写入括号中后,该资源不能被重新赋值,否则会编译报错。

    下划线使用限制

    jdk8中标识符可以独立使用"_"来命名。

    image-20210226174719011

    jdk9后,限制了该写法,不允许单独使用下划线作为标识符

    image-20210226174757995

    但是使用两个下划线就可以。

    String数据结构的变化

    底层存储从char数组改成了byte数组

    同时,StringBuilder和StringBuffer也有这样的变化。

    集合工厂方法

    创建一个只读、不可改变的集合。(Set同样也有of方法)

    List<Integer> list = List.of(1, 2, 3, 4);
    list.add(5);
    

    image-20210227130949719

    Map<Integer, String> map = Map.of(1, "1", 2, "2", 3, "3");
    map.put(4,"4");
    

    image-20210227131054041

    增强Stream Api

    Java9中,Stream接口中添加了4个新的方法:dropWhile,takeWhile,OfNullable,iterate重载方法。

    takeWhile

    用于从stream中获取一部分数据,接收一个Predicate来进行选择,在有序的Stream中,takeWhile返回从开头开始的尽量多的元素。

    ArrayList<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7));
    list.stream().takeWhile(x -> x <= 5).forEach(System.out::println);
    System.out.println(list);
    

    image-20210227132227018

    dropWhile

    dropWhile与takeWhile相反,返回剩余元素

    ArrayList<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7));
    list.stream().dropWhile(x -> x <= 5).forEach(System.out::println);
    System.out.println(list);
    

    image-20210227132450406

    ofNullable

    Java8中Stream不能完全是null(Stream中只有一个元素,不能是null),否则会报空指针异常。

    java9中可以通过ofNullable方法为我们创建一个氮元素Stream,可以包含一个非空元素。

    Stream<Object> stream = Stream.ofNullable(null);
    System.out.println(stream.count());
    

    iterate重载方法

    jdk8中提供了iterate的静态方法:

    public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) 
    

    通过此方法,我们可以创建Stream的无限流

    long count = Stream.iterate(1, i -> i + 1).limit(20).count();
    System.out.println(count);
    

    jdk9中提供了iterate的重载方法,通过此方法我们限制iterate迭代的次数

    public static<T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)
    
            long count2 = Stream.iterate(1, j -> j <= 20, i -> i + 1).count();
            System.out.println(count2);
    

    Optional的Stream方法

    ArrayList<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);
    
    Optional<ArrayList<Integer>> op = Optional.ofNullable(list);
    Stream<ArrayList<Integer>> stream = op.stream();
    stream.flatMap(Collection::stream).forEach(System.out::println);
    

    image-20210227134350903

    InputStream的transferTo方法

    InputStream新增了transferTo方法,可以将数据直接传输到输出流中,实际底层上还是用read+write那一套

    public long transferTo(OutputStream out) throws IOException {
        Objects.requireNonNull(out, "out");
        long transferred = 0;
        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
        int read;
        while ((read = this.read(buffer, 0, DEFAULT_BUFFER_SIZE)) >= 0) {
            out.write(buffer, 0, read);
            transferred += read;
        }
        return transferred;
    }
    
    public class InputStreamTest {
        public static void main(String[] args) throws IOException {
            InputStream is = InputStreamTest.class.getClassLoader().getResourceAsStream("a.txt");
            FileOutputStream fos = new FileOutputStream("a2.txt");
            is.transferTo(fos);
        }
    }
    

    可以用此方法,将a.txt内容转换到a2.txt中

  • 相关阅读:
    ADO.NET入门教程(五) 细说数据库连接池
    Delphi下使用指针的简单总结
    Delphi
    Delphi
    Delphi
    TXLSReadWriteII5 单元格读写
    [Delphi]Delphi开发的一些技巧
    TXLSReadWriteII2版本导出Excel文件:
    Tomcat使用startup启动,一闪而过,如何查看出错信息
    【转】Java保留固定小数位的4种方法
  • 原文地址:https://www.cnblogs.com/wwjj4811/p/14455538.html
Copyright © 2020-2023  润新知