文章目录
动态加载类 就是在运行时需要这个类的时候再加载到内存,
而不是在编译时刻就加载好,
一般 功能性的类 用动态加载的方式——
Class.forName() 和 newInstance()
一、从一个简单的案例说起:
现有一个类Table如下,
它的功能是:
根据输入来判断
运行 Word 程序 还是 Excel 程序:
Word类 和 Excel类 如下,
此处用 打印字符串 模拟运行:
测试一下,运行成功:
二、分析一下:
嘿嘿嘿,成功了,虽然很开心,
但我们还是一起分析一下
程序内部运行过程吧:
每一次运行,
不论执行 IF 的哪一个分支,
在 运行之前 的 编译时刻,
内存中都会先 new 出新的空间——
这里也就是 word 和 excel 两个对象的空间。
P.S.:new是 静态加载类的方式,在编译时刻就进行对象的创建。
但是,你有没有想过下面这两个问题:
①一旦 Word 或者 Excel 其中之一代码有错,
这个项目就会报错不能运行,
也就是说,
项目的一个功能不能用,
其他功能都不能用,
这显然很不合理。
②如果要增加一个新的功能,
比如说: PPT ,
那就需要修改 IF 语句,
修改就意味着要重新
编译、测试、发布,
显然非常麻烦。
那有什么改进的方法吗?
这时就要用到 动态加载类 。
三、动态加载类:
1.Java中的Class类:
我们创建一个A类的对象:
A a1=new A();//对象
Class类的作用是 用来表示A类本身 ,
由此就可以访问 A类的所有信息:
包括:方法、成员变量、构造函数、所在包、是否是接口等。
Class类有三种方式来表示A这个类本身:
Class c1=A.class; //c1这个对象代表A这个类,任何类都有一个隐含的静态成员变量class
Class c2=a1.getClass(); //c2这个对象代表A这个类,Object类的方法
Class c3=Class.forName("javacore.A"); //也代表了动态加载类,在运行时加载类,而非编译时
通过c1c2c3,我们就可以获取类的任何信息了(详细内容请见 附录P.S.1)。
我们也可以通过c1c2c3直接获取A类的对象:
A aa=(A)c1.newInstance();//会调用无参数的构造方法来产生对象,返回Object,需要强制类型转换
2.动态加载类:
它用到上面Class的语法——
Class.forName()和newInstance()
这里用到了接口来实现对象的多态(详细内容请见 附录P.S.2)