JAVA9 新特性总结

JAVA 9

模块机制

当我们导入一个jar包做为依赖时(包括JDK官方库),实际上很多功能我们并不会用到,但是由于他们是属于同一个jar捆绑在一起,这样就会导致我们可能只用到一部分功能,但是需要引用一个完整的类库,实际上我们可以把用不到的类库排除掉,大大降低jar库的规模。

JAVA9 引入了模块机制来对这种情况进行优化,在之前我们的项目如下:

引入模块机制之后,如下:

可以看到,模块可以由一个或者多个在一起的Java包组成,通过江这些包分出不同的模块,我们就可以按照模块的方式进行管理了。这里我们创建一个新的项目,并在src目录下,搭建module-info.java文件表示此项目采用模块机制,我们可以在idea右键创建 module-info.java 文件

在 JAVA 9 如果不创建 module-info.java,则所有包都会被加载,若希望分的清楚,可以创建 module-info.java,一旦创建 module-info.java 则只会导入 JAVA9的部分基础包,如 Logger 类,以前用的是 java.util.logging 的,但创建 module-info.java 后只有 java.lang.System 下的,我们可以在 module-info.java 导入我们想用的

如果加了 module-info.java 则需要清楚了解你需要使用的包位于哪里,如果使用反射的话,没有导入这样的包会报错,如下对 String 做反射报错结果

JAVA9 的反射 API 封装和安全性得到了改进,如果模块没有明确授权给其他模块使用反射的权限,那么其他模块是不允许使用反射进行修改的,看来Unsafe类是完不成了。对于模块的机制具有以下四中类型:

  • 系统模块:来自JDK和JRE的模块(官方提供的模块,比如我们上面用的),我们也可以直接使用 java --list-modules 命令来列出所有的模块,不同的模块会导出不同的包供我们使用。
  • 应用程序模块:我们自己写的JAVA模块项目
  • 自动模块:可能有些库并不是Java9以上的模块项目,这种时候需要做兼容了,默认情况下是直接导出所有的包,可以访问所有其他模块提供类,不然之前版本的库就用不了了。
  • 未命名的模块:我们自己创建的一个Java项目,如果没有创建 module-info.java,那么会按照未命名模块进行处理,未命名模块同样可以访问所有其他模块提供的类,这样我们之前写的java8 代码才能政策地在java9以及之后的版本下运行。不过,由于没有使用java9的模块新特性,未命名模块只能默认暴露给其他未命名的模块和自动模块,应用程序模块无法访问这些(实际上就是传统java8以下的变成模式,因为没有模块只需要导包就行)

我们也可以自己写一些jar提供别人使用,在使用的时候使用 module-info.java 让控制哪些导入,哪些不导入

requires 还可以加 static 关键字,加了static之后,在编译的时候会依然有这个包,但是在运行的时候就会报找不到该包。

除了 exports 可以跟 to 关键字,代表暴露给谁,指明哪些包可以使用我这个包

当 a 使用了某些包后,默认 b 是不能使用 a 所使用的包的,也就是没有传递性,我们所导入包 requires 后面加 transitive 关键字让其把依赖传递

如果我们对 以上的 User 使用反射,也是不能直接使用的,会报错

需要使用 open 关键字对整个所需要反射的 module 进行描述,如果不想对 module 进行描述,也可以对 module 下的需要反射类所在的包进行 opens 描述

uses语句使用服务接口的名字,当前模块就会发现它,使用java.util.ServiceLoader类进行加载,必须是本模块中的,不能是其他模块中的.其实现类可以由其他模块提供.

JShell交互式编程

java9 为我们提供了一种交互式变成工具Jshell,你还别说,真有Python的味道

C:\Users\User>jshell
|  欢迎使用 JShell -- 版本 17.0.3.1
|  要大致了解该版本, 请键入: /help intro

jshell>

环境配置完成后,我们只需要输入 jshell 命令即可开启交互式编程了,它支持我们一条一条命令进行操作。比如我们来做一个简单的计算:

jshell> int a = 10
a ==> 10

jshell> int b = 10
b ==> 10

jshell> int c = a/b
c ==> 1

jshell>

使用 /vars 可以看到我们定义的所有变量

jshell> /vars
|    int a = 10
|    int b = 10
|    int c = 1

我们也可以创一个方法,并通过 /method 方法列出所有方法,并调用方法

jshell> public int max(int a,int b){
   ...>     return a > b? a: b;
   ...> }
|  已创建 方法 max(int,int)

jshell> /method
|    int max(int,int)

jshell> max(19,20)
$5 ==> 20

接口中的private方法

在Java8中,接口中的方法支持添加 default 关键字来添加默认实现;而在java9中,接口再次得到强化,提供接口中可以存在私有方法。

package com.b;

public interface Test {

    default void test(){
        this.test1();
        System.out.println("默认方法");
    }

    private void test1(){
        System.out.println("私有方法");
    }

    static void test2(){
        System.out.println("静态方法");
    }

}
package com.b;

public class MainB implements Test {

    public static void main(String[] args){
        MainB mainB = new MainB();
        mainB.test();
        Test.test2();
    }

}

私有方法
默认方法
静态方法

集合类新增工厂方法

在之前,如果我们想要快速创建一个Map可以通过以下方式

    public static void main(String[] args){
        Map<String,String> map = new HashMap(3);
        map.put("key","value");
        
        map = new HashMap<String,String>(3){{
            put("key","value");
        }};    
    }

在java9之后,我们可以直接通过 of 方法来快速创建,但是这种方式就不能使用 put 方法

Map<String, String> key = Map.of("key", "value");

改进的Stream API

    public static void main(String[] args){
        // java8 只能使用of,为null会报错
        Stream.of(null).forEach(System.out::println);

        // Java9 允许为null
        Stream.ofNullable(null).forEach(System.out::println);

        // java8 允许生成无限的数据,可以用limit限制
        Stream.iterate(0,i -> i+1).limit(20).forEach(System.out::println);

        // java9 变为使用表达式来限制 相当于 for (int i=0;i<20;i++)
        Stream.iterate(0,i -> i < 20,i -> i + 1).forEach(System.out::println);

        // java9 还增加了截断流, i < 10,生成 小于 10 的数据
        Stream.iterate(0,i -> i < 20,i -> i + 1).takeWhile(i -> i>10).forEach(System.out::println);

        // java9 还增加了删除流, i < 10,小于 10 的数据都被删掉,相当于值打印 i >= 10 的数据
        Stream.iterate(0,i -> i < 20,i -> i + 1).dropWhile(i -> i>10).forEach(System.out::println);
    }

其他小改动

java7新增了Try-with-resources(只有实现了 AutoCloseable 或 Closeable 接口的资源),JAVA9有对try 增强

public void java8(){
        try (InputStream stream = Files.newInputStream(Paths.get("pom.xml"))){
                stream....
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    public void java9() throws IOException {
        InputStream stream = Files.newInputStream(Paths.get("pom.xml"));
        try (stream){
            for (int i = 0; i < 100; i++) {
                System.out.println(stream.read());
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }

Optional 增强

    public void java8(){
        String s = null;
        Optional.ofNullable(s).ifPresent(str -> System.out.println("str = " + str));
    }

    public void java9() throws IOException {
        String s = null;
        // 类似于 if else
        Optional.ofNullable(s)
                .ifPresentOrElse(str -> System.out.println("str = " + str),() -> System.out.println("MainB.java9"));
    }

    public void java9_1()  {
        String s = null;
        // 类似于 if else
        Optional.ofNullable(s)
                .ifPresentOrElse(str -> System.out.println("str = " + str),() -> System.out.println("MainB.java9"));
    }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,063评论 6 510
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,805评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,403评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,110评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,130评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,877评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,533评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,429评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,947评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,078评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,204评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,894评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,546评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,086评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,195评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,519评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,198评论 2 357

推荐阅读更多精彩内容