java 模块化


java9出了模块,作为一名主要用java的程序员,所以要提前学习,保持一颗好学的心.

1.创建模块

 新建java project com.horstmann.greet,eclipse新版会提示是否要创建模块,

,如果在此输入模块名字的话就会生成一个module-info.java类,是模块的描述信息类,主要包含以下内容

 到此一个模块就创建好了,如果没有在创建的时候输入模块,也可以自己新建module-info.java类来创建模块.

2. 暴露模块

我们创建一个接口

package com.horstmann.greet;

public interface Greeter {
    static Greeter newInstance() {
        return new com.horstmann.greet.internal.GreeterImpl();
    }
    String greet(String subject);
    
}

和它的实现类

package com.horstmann.greet.internal;

import com.horstmann.greet.Greeter;

public class GreeterImpl implements Greeter {

    @Override
    public String greet(String subject) {
        // TODO Auto-generated method stub
        return "Hello, " + subject + "!";
    }

}

目录结构如下

 一般来说都会暴露模块的接口,而不是实现类,类似于es6中的模块,我们直接exports包即可

module com.horstmann.greet {
    exports com.horstmann.greet;
}

这样其他模块就可以引用即可

3.引用暴露的模块

新建模块 v2ch09.exportedpkg

 创建类HelloWorld

在eclipse中右键属性引入刚刚的模块

 编辑module-info.java即可引入导出的类

module v2ch09.exportedpkg {
    requires com.horstmann.greet;
    requires hellomod.test;
}
public class HelloWorld {
    public static void main(String[] args) {
        Greeter greeter = Greeter.newInstance();
        System.out.println(greeter.greet("Modular World"));
    }
}

直接运行helloworld类,即可看到结果

通过exports和requires,我们可以在module-info中对模块的权限进行控制,需要哪些模块,不需要哪些模块,非常方便. 

4.模块和反射

模块不能通过反射访问私有属性比如:

package hellomod.test;

public class ReflectTest {
    private Integer name;

    public ReflectTest(Integer name) {
        super();
        this.name = name;
    }
}

我在另一个模块通过反射访问name,会报错

ReflectTest reflectTest = new ReflectTest(123);
        Field field = reflectTest.getClass().getDeclaredField("name");
        System.out.println(field.getInt(reflectTest));

 解决: 在要访问的模块中添加open关键词即可

open module hellomod.test{
    exports hellomod.test;
}

如图 我们在module 前面添加 open即可

或者添加exports和opens关键词

module hellomod.test{
     exports hellomod.test;
     opens hellomod.test;
}

即可开放反射访问权限

 5.自动模块和不具名模块

自动模块: 就是把jar文件放到模块路径上的模块. 为了改造以前的方式成模块,jar文件直接可以放到模块路径上成为一个新的模块

所有包都导出,包含其他所有模块

不具名模块: 不在模块路径中的类组成的模块.

可以访问其他模块,但是不能被其他模块访问