1、静态加载和动态加载的区分:
我们在理解动态加载的同时,需要区分Java的编译和运行:
编译时加载属于静态加载,我们平时开发中使用最多的就是静态加载,new对象都属于静态加载类,在编译时加载所有可能使用到的类(虽然有可能用不到)。A a = new A();
运行时加载属于动态加载,我们在表示Class的实例对象的时候使用到的第三种方式,即 class.forName(),在编译时不会报任何错误,只有在使用类并且该类不存在时,才会报ClassNotFoundException 的异常。然后可以通过类的类类型创建该类的对象,即:A a = (A)class.forName("test.A").newInstance();
2、为什么要使用动态加载类?
在平时开发中,一些开发工具是我们是分不清编译和运行的,因为开发工具已经帮我们做了,我们可以在一些编辑器中来编写案例来区分编译和运行。
静态加载类——编译时加载
class Office
{
public static void main(String[] args)
{
if("word".equals(args[0])){
Word w = new Word();
w.start();
}
if("Excel".equals(args[0])){
Excel e = new Excel();
e.start();
}
}
}
因为new对象是静态加载类,在编译时就会加载Word类和Excel类,但是Word类和Excel类是不存在的,所以Office类是编译不成功的,即使Word类存在,Excel类不存在,Office类也是编译不成功的,所以我们在平时开发中假设有10个功能,如果有1个功能用不了,其余9个功能也不能使用,这就是编译时加载导致的。
动态加载类——运行时加载
class OfficeNew
{
public static void main(String[] args)
{
try{
//动态加载类,通过类类型创建该类的对象。
Class c = Class.forName(args[0]);
OfficeBetter of = (OfficeBetter)c.newInstance();
of.start();
}catch(Exception e){
e.printStackTrace();
}
}
}
OfficeBetter我们可以看做是使用标准,使用的每一个功能都来实现这个标准。
interface OfficeBetter
{
public void start();
}
然后Word类和Excel类共同实现OfficeBetter标准:
class Word implements OfficeBetter
{
public void start(){
System.out.println("word....start");
}
}
class Excel implements OfficeBetter
{
public void start()
{
System.out.println("excel....start");
}
}
如果需要迭代新的功能,我们不需要更改使用类OfficeNew,只需要添加新的的功能并且实现OfficeBetter标准即可,这就是动态加载类给我们带来的好处。
补充:
java中class.forName和classLoader都可用来对类进行动态加载。前者除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块。而classLoader只是将.class文件加载到jvm中,不会执行static中的内容,只有在newInstance才会去执行static块。Class.forName(name, initialize, loader)带参函数也可控制是否加载static块(initialize为true是表示进行初始化,initialize为false表示不需要进行初始化)。并且只有调用了newInstance()方法才会调用构造函数,创建类的对象 。