class.forName("类的全称");java
编写一个Office.java以下:命令行
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(); } } }
而后用命令行去编译该文件,会报错:code
由于Word类,Excel类都不存在。对象
如今把Word类补全,并编译经过:blog
class Word { public static void start() { System.out.println("word...start..."); } }
此时再去编译Office.java,就只会提示Excel类找不到:接口
经过new建立对象,是静态加载类,在编译时刻就要去加载全部可能使用到的类,无论某些类是否真的须要用到。io
如今咱们只想用Word,但程序一直在报错:Excel这个类找不到。实际应用当中,咱们但愿Word存在,Word就能用,当要使用Excel的时候,再提示咱们Excel找不到。这个程序就没办法作到,若是未来有许多功能,只要有一个功能有问题,其余全部功能就都没法使用,这就是编译时刻加载致使的。编译
咱们如今想要作到用哪一个类就加载哪一个类,不用就不加载。经过动态加载类就能够解决该问题。class
建立一个OfficeBetter.java,以下:程序
class OfficeBetter { public static void main(String[] args) { try { //动态加载类,在运行时刻加载 Class c = Class.forName(args[0]); } catch (Exception e) { e.printStackTrace(); } } }
此时编译该类不会报任何错。传入Word参数运行也不会报错:
只有当咱们传入不存在的类时,运行才会报错(但编译不会保存):
接下来,咱们能够经过类类型去建立对象,那么问题就来了:
class OfficeBetter { public static void main(String[] args) { try { //动态加载类,在运行时刻加载 Class c = Class.forName(args[0]); //经过类类型,建立该类的对象 //Word w = (Word) c.newInstance(); //Excel e = (Excel) c.newInstance(); } catch (Exception e) { e.printStackTrace(); } } }
咱们这里是该建立Word对象呢,仍是该建立Excel对象呢,或者咱们传入的是其余对象又该怎么办呢?
若是咱们想适应以后传入的全部对象,咱们就须要提供一个统一的标准,建立接口类OfficeAble.java,以下:
interface OfficeAble { public void start(); }
而后让咱们的类遵循该标准:
class Word implements OfficeAble { public void start() { System.out.println("word...start..."); } }
这样咱们就能够经过这个标准,建立全部实现了该接口的对象:
class OfficeBetter { public static void main(String[] args) { try { //动态加载类,在运行时刻加载 Class c = Class.forName(args[0]); //经过类类型,建立该类的对象 //Word w = (Word) c.newInstance(); //Excel e = (Excel) c.newInstance(); //经过标准接口建立对象 OfficeAble oa = (OfficeAble) c.newInstance(); //调用对象方法 oa.start(); } catch (Exception e) { e.printStackTrace(); } } }
此时从新编译上面的文件,运行Word,就不会报错:
若是想让Excel也可使用,只需让其实现OfficeAble接口就能够(不须要从新编译OfficeBetter.java),一样的,未来添加了更多新的实现,都只要遵循该标准添加新的类,OfficeBetter这个类永远都不须要修改,这就是动态加载类。
通常来讲功能性的类,咱们都会使用动态加载类,而不使用静态加载类。