Class.forName方法与动态加载

来源:互联网 发布:淘宝怎么做生意好 编辑:程序博客网 时间:2024/06/05 03:22

可以通过Class.forName("类的全类名")方法创建一个类的类类型。不仅如此,这个方法还表示了动态加载类。

动态加载类与静态加载类的区分:

  • 编译时刻加载的类称为静态加载类。
  • 运行时刻加载的类称为动态加载类。

 

静态加载的不足:在编译时就会把所有类都加载,不论是否使用

Office.java类

 1 class Office{ 2     public static void main(String args[]){ 3             if("Word".equals(args[0])){ 4                 Word word=new Word(); 5                 word.start(); 6             } 7             if("Excel".equals(args[0])){ 8                 Excel excel=new Excel(); 9                 excel.start();10             }11     }12 }

思考:这个程序是否能够通过编译?

Office.java:4: 错误: 找不到符号                                Word word=new Word();                                ^  符号:   类 Word  位置: 类 OfficeOffice.java:4: 错误: 找不到符号                                Word word=new Word();                                              ^  符号:   类 Word  位置: 类 OfficeOffice.java:8: 错误: 找不到符号                                Excel excel=new Excel();                                ^  符号:   类 Excel  位置: 类 OfficeOffice.java:8: 错误: 找不到符号                                Excel excel=new Excel();                                                ^  符号:   类 Excel  位置: 类 Office4 个错误

 思考:毫无疑问肯定是编译失败的,因为Word、Excel类还没有定义,当然也不存在两个start()方法。正因为如此编译失败也就理所当然了,但是如果多考虑一点:Word用吗?Excel用吗?也许这两个类与两个方法都用不到,既然都不用,可是编译却无法通过。

Word.java:编写Word类和start方法

1 class Word {2     public void start(){3         System.out.println("Word...starts..");4     }5 }

继续编译这个程序:现在只报了两个关于Excel的错误。

 F:\xj>javac Word.java  F:\xj>javac Office.java Office.java:8: 错误: 找不到符号                                 Excel excel=new Excel();                                 ^   符号:   类 Excel   位置: 类 Office Office.java:8: 错误: 找不到符号                                 Excel excel=new Excel();                                                 ^   符号:   类 Excel   位置: 类 Office 2 个错误

 

思考:此刻再来思考和上面一样的问题,如果只需要Word,不需要Excel,但是这个程序也依然运行不了。因为程序做的是静态加载。即:new方式创建对象都是静态加载类

使用静态加载导致了不管这些类是否使用,在编译的时候就必须加载所有可能使用到的类。

 

然而在实际中,希望Word存在,Word就可以用;当用Excel的时候java编译器你再提醒我Excel有问题。就例如我们程序中有100个程序,但是只要是一个有了问题,其他的都用不了。其实这并不是我们想要看到的。这就是编译时加载导致的。所以希望利用运行时动态加载来解决该问题。

 

动态加载

通过new方法来创建对象都是静态加载,但是通过forName()方法去可以进行动态加载。

OfficeBetter.java:这里采用动态加载

 1 class OfficeBetter{ 2     public static void main(String args[]){ 3         try{ 4             //动态加载类在运行时刻。编译的时候并不会报错,他才不会管你是哪个类呢。 5             Class classWord=Class.forName(args[0]); 6         }catch(Exception e){ 7             e.printStackTrace(); 8         } 9     }10 }

问题:接下来创建对象又有了问题了,如果这里面使用Word word=(Word)classWord.newInstance(),此刻如果传入的是Excel就出现问题了;如果往Excel做强制类型转换,那么如果传入Word同样会出现问题。

思路:所以这里面要提升一下思想,给Word与Excel制定一个标准,然后让Word与Excel实现这个标准OfficeAble。完整代码如下:

OfficeBetter.java

 1 class OfficeBetter{ 2     public static void main(String args[]){ 3         try{ 4             Class class01=Class.forName(args[0]);         5             OfficeAble oa=(OfficeAble)class01.newInstance(); 6             oa.start(); 7         }catch(Exception e){ 8             e.printStackTrace(); 9         }10     }11     12 }

OfficeAble.java:接口

1 interface OfficeAble{2     public void start();3 }

Word.java

1 class Word implements OfficeAble{2     public void start(){3         System.out.println("Word...starts..");4     }5 }

此刻编译都是完全可以通过, 然后我们分别输入Excel与word

F:\xj>java OfficeBetter Exceljava.lang.ClassNotFoundException: Excel        at java.net.URLClassLoader.findClass(Unknown Source)        at java.lang.ClassLoader.loadClass(Unknown Source)        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)        at java.lang.ClassLoader.loadClass(Unknown Source)        at java.lang.Class.forName0(Native Method)        at java.lang.Class.forName(Unknown Source)        at OfficeBetter.main(OfficeBetter.java:5)F:\xj>java OfficeBetter Word 

 发现:当输入Excel的时候才会发生错误,但是当输入Word的时候完全可以使用。
和之前的相比,不同的是,这里面编译的时候没有任何问题。word也可以正常使用。只有在输入Excel,开始运行Excel的时候才会报错——notFoundException。 这正是我们需要的动态加载:在编译的时候不去理会,在使用的时候再去判断。
接下来就可以创建对象了:通过类类型创建该类的对象。

 运行结果:

F:\xj>javac OfficeBetter.javaF:\xj>java OfficeBetter WordWord...starts.. 

 
当然类似Word类,也可以建一个Excel类:

class Excel implements OfficeAble{    public void start(){    System.out.println("Excel...starts..");    }}F:\xj>javac Excel.javaF:\xj>java OfficeBetter ExcelExcel...starts...

 这里面OfficeBetter这个类不用再编译,直接运行就可以了

功能性的类一般使用动态加载,而不是静态加载

 

END.

原创粉丝点击