今天博主继续学习基础系列之反射专题;今天学习的内容是动态类的加载,我们以举简单的例子来进行一步步说明:
首先我们看一个例子:OfficeTest.java
/**
* @Description 测试类
* @Date 2019/1/3 14:22
* @Created by FLXH
*/
public class OfficeTest {
public static void main(String[] args) {
//new方法创建对象,在编译时刻就需要加载所有可能使用到的类
if ("Word".equals(args[0])) {
Word w = new Word();
w.start();
}
if ("Excel".equals(args[0])) {
Excel e = new Excel();
e.start();
}
}
}
当我们缺少Word和Excle任何一个类的时候,代码都无法编译成功,从上面代码我们可以知道new方法创建对象,在编译时刻就需要加载所有可能使用到的类,假如new了100个类,有一个类没有,则其他99类就算都正常,这个测试类也无法通过编译,这就说明了一点:
new方法创建对象:属于静态加载类
由此我们引申出动态加载类:我们来看下面这个例子:
首先我们列举几个用到的类:
1.一个接口:里面包含一个start抽象方法
/**
* @Description 公有类
* @Date 2019/1/3 14:12
* @Created by FLXH
*/
public interface ClassOffice {
//抽象方法
public void start();
}
2.Word类:需要实现ClassOffice接口
/**
* @Description 公有类
* @Date 2019/1/3 14:12
* @Created by FLXH
*/
public interface ClassOffice {
//抽象方法
public void start();
}
3.Excel类:需要实现ClassOffice接口
/**
* @Description Excel类
* @Date 2019/1/3 14:13
* @Created by FLXH
*/
public class Excel implements ClassOffice {
@Override
public void start() {
System.out.println("Excel ... Start");
}
}
4.再看一段动态测试类的代码:
/**
* @Description 动态测试
* @Date 2019/1/3 14:48
* @Created by FLXH
*/
public class DynamicTest {
public static void main(String[] args) {
try {
//动态加载类
Class c = Class.forName(args[0]);
//使用接口来接收动态传入的类 这些类需要实现这个接口
ClassOffice co = (ClassOffice) c.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
根据上面的代码可以知道,当我们通过Class.forName这样的方式去加载类的时候,是可以通过编译的,具体的类可以通过args[0]传入进来,这就和直接去new创建类有区别了,一个静态的,而另一个是动态的;
这里又衍生出一个问题,由于在编译的时候我不知道传那个类,所以在通过"类类型"(Class Type:上一篇博客有讲)的newInstance方法创建对象时,这样在强制转换的时候有可能出错,比如:从这个例子来说,你强制转换成Word类,那么有可能传进的是Excel类,就会发生转换类型的错误;所以我们声明了一个ClassOffice接口,其他两个类实现这个接口,即可把类型转换成ClassOffice,这样传Word或者Excel就都没有问题了
5.好了,总结一下,主要注意下new创建静态加载类和Class.forName动态加载类,还有接口进行强制转换的小技巧,大家一起加油!