java9发布有一段时间了,模块化是java9的一个重要新特性。
今天有时间,就体验一把java9的模块化功能。
创建模块
首先创建src和target目录,src目录用于存放源代码,target目录用于存放编译结果。
src目录下创建一个goods(商品)目录,作为goods模块
goods目录下创建一个module-info.java,内容为
module goods {}
这里简单声明了一个模块。
goods目录下创建一个com.binecy.goods.Goods类,
此时src目录结构为
$ tree src/
src/
└── goods
├── com
│ └── binecy
│ └── goods
│ └── Goods.java
└── module-info.java
Goods内容为
package com.binecy.goods;
public class Goods {
public Goods(String name) {
this.name = name;
}
private String name;
public String getName() {
return name;
}
public static void main(String[] args) {
Goods g = new Goods("apple");
System.out.println("I'm Goods:" + g.getName());
}
}
一个很简单的java类。
编译模块
首先,编译goods这个模块,
javac --module-source-path src -d target $(find src -name '*.java')
--module-source-path:指定查找模块源文件的路径
-d:指定放置生成的class的位置
运行模块
运行Goods类
java --module-path target -m goods/com.binecy.goods.Goods
--module-path:指定模块编译后class目录
-m 以<模块>/<主类>
的格式指定要运行的类。
引用模块
下面添加一个warehouse模块,它需要引用goods模块的Goods类。
首先,goods目录的module-info.java要需改为
module goods {
exports com.binecy.goods;
}
表示该模块暴露com.binecy.goods包给其他模块调用,class用public修饰只能暴露给当前模块调用,无法暴露给其他模块调用。
src目录下添加一个warehouse目录,warehouse目录
添加module-info.java,内容为
module warehouse {
requires goods;
}
requires goods;
表示依赖于goods模块。
warehouse添加com.binecy.warehouse.Warehouse类。
此时src目录结构为
$ tree src
src
├── goods
│ ├── com
│ │ └── binecy
│ │ └── goods
│ │ └── Goods.java
│ └── module-info.java
└── warehouse
├── com
│ └── binecy
│ └── warehouse
│ └── Warehouse.java
└── module-info.java
Warehouse类的内容为:
package com.binecy.warehouse;
import com.binecy.goods.*;
public class Warehouse {
private Goods goods;
public Warehouse(Goods goods) {
this.goods = goods;
}
public static void main(String[] args) {
Goods g = new Goods("apple");
Warehouse w = new Warehouse(g);
System.out.println("I have Goods:" + w.goods.getName());
}
}
重新编译代码
javac --module-source-path src -d target $(find src -name '*.java')
运行Warehouse
java --module-path target -m warehouse/com.binecy.warehouse.Warehouse
感觉比较有意思的是,使用public修饰的类只能在当前模块使用。某些情况下,有些类确实需要提供给同一功能模块的不同package调用,但又想暴露给其他模块,这时这个特性就很有用了。
看了一下jdk11的源码结构,已经使用了模块化组织代码。模块化应该也是java发展的一个趋势了。
参考:
Java 模块化系统初探
Java 9 模块系统
idea中使用模块化:Java9 手把手教你实现模块化