0x01 前言
Java动态加载类主要是为了不改变主程序代码,解除耦合而出现的,通过修改配置文件就可以调用不同的实例对象执行不同的功能。
这样的话就可以按需加载,我们需要什么类,就加载什么类,某个类的状态,不会影响到另一个类的使用。
例如-现在要开发一个 Office组件:
功能有: Excel, Word, Ppt
但是因为项目工期问题,那么就只完成了 Excel, Word 功能
Ppt功能还没写完,但是又需要先上线,于是就准备等Ppt功能写好了以后在更新该功能
静态加载: 如果是静态加载的话,那么我们写完 Ppt功能 的时候就需要上去修改 Office组件 的代码,并且重新编译这样才能引入 Ppt功能,这样就不是很方便了,并且要是不需要这个功能了,还要上去重新修改 Office组件 的代码,并重新编译,很麻烦
动态加载: 如果是动态加载的化,那么我们写完 Ppt功能 以后只需要把该源码放在项目里面去,然后修改一下配置文件以后就可以了,这样就不需要重新编译了.
而且要是我们不喜欢Ppt这个功能,删除了也不用修改 Office组件 的代码,只需要修改一下配置文件,并把 Ppt.class 文件删除即可
0x02 Java动态加载类-例子
0x02.1 目录结构
# 目录结构
├── 反射
│ └── java动态加载类1
│ ├── OfficeAble.java
│ ├── OfficeBetter.java
│ ├── Excel.java
│ ├── Word.java
│ ├── Ppt.java
0x02.2 实验目标
创建一个 Office 的类,可以简单的动态加载 Excel, Word, Ppt 并输出内容
0x02.3 接口(interface)-建立功能类的父类
接口(interface)是抽象方法和常量值的定义的集合。
从本质上来看, 接口是一种特殊的抽象类,这种抽象类只包含常量与方法的定义,而没有变量与方法的具体实现。
因此为来使程序有更好的扩展性,我们添加一个接口,后面所有的功能类都需要继承并实现该接口。
# 接口类-所有的功能类都要继承它并实现该接口
package 反射.java动态加载类1;
public interface OfficeAble {
public void start();
}
0x02.4 OfficeBetter组件类
# 通过该类调用的各种功能类
package 反射.java动态加载类1;
public class OfficeBetter {
public static void main(String[] args) {
try {
// 动态加载类,在运行时加载
Class c = Class.forName("反射.java动态加载类1." + args[0]);
// 通过类类型,创建该类对象
OfficeAble oa = (OfficeAble)c.newInstance();
// 运行对应的方法
oa.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
0x02.5 功能类
0x02.5.1 Excel-功能类
package 反射.java动态加载类1;
public class Excel implements OfficeAble{
public void start() {
System.out.println("Excel ... start");
}
}
0x02.5.2 Word-功能类
package 反射.java动态加载类1;
public class Word implements OfficeAble{
public void start() {
System.out.println("Word ... start");
}
}
0x02.5.3 Ppt-功能类
package 反射.java动态加载类1;
public class Ppt implements OfficeAble{
public void start() {
System.out.println("Ppt ... start");
}
}