近日看了篇文档,有个地方有些不清楚。
请教了。
"即使你声明了一个类对象,不实例化也不会加载,说明只有真正用到那个类的实例即对象的时候,才会执行加载。"
问:
“实例化”是创建对象,内存开启空间,这个我知道。
什么是“加载”,和“实例化”有何区别?请解释的详细些。
请教了。
"即使你声明了一个类对象,不实例化也不会加载,说明只有真正用到那个类的实例即对象的时候,才会执行加载。"
问:
“实例化”是创建对象,内存开启空间,这个我知道。
什么是“加载”,和“实例化”有何区别?请解释的详细些。
main(){
.
.
.
String str = new String();//当然是执行完这句,str生成对象。何以体现“动态加载”?
.
.
.
}
你上面的代码是在编码是就知道好要加载一个String对象。
main(){
.
.
.
if(...){
String str = new String();//当然是执行完这句,str生成对象。何以体现“动态加载”?
}
.
.
.
}
* 在程序代码中无法知道运行到System.out.println(dynaObj.toString())语句时dynaObj是什么类型的对象.
* 只有在程序运行的时候通过命令行参数才能决定dynaObj是String类型的对象还是Date类型的对象.
* 当然可以通过其它方式传递参数信息,比如通过其它方法调用. 这就是简单的动态加载.
*
* @param args
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public static void main(String[] args) throws ClassNotFoundException,
InstantiationException, IllegalAccessException {
Object dynaObj = null;
if (args[0].equals("s")) {
dynaObj = Class.forName("java.lang.String").newInstance();
} else if (args[0].equals("d")) {
dynaObj = Class.forName("java.util.Date").newInstance();
}
System.out.println(dynaObj.toString());
}}
2 手动加载,由程序员代码完成。两种加载方式的特点1 自动加载:方便,
也就是说程序员只要在类中引用了其他包中的类型,在运行时当第一次用到这个类的时候jvm会自动加载这个类
2 手动加载:灵活,
对大系统的程序部署,版本控制都有好处,在这里就不多说了。
手动加载类的问题:1 可能会有版本问题,
如果一个类的类加载器在运行时刻加载了同一类的不同版本,那么在调用这个类的时候究竟应该调用哪个版本呢。2 类只识别类自己的加载器加载的其他类。
类手动加载的原则:1 类加载器不应该加载同一个类两次。2 类加载器在加载类的时候要先委托父的加载器加载。3 类的加载器加载类的时候被加载的类所引用的基础类是用jvm自动加载的,这样保证了版本不会冲突。
在一个大型的系统中,肯定会用到动态加载,这个时候好处自然就体现出来了,
在一些大型的应用中,你不可能预知到所有的情况,也就是说你在代码中不可能穷举到所有的情况,
你有一些在执行的时候才能确定的东西(简单的理解是类型,说大一点是模块,子系统什么的),
这个时候java好处自然就体现出来了.imA的例子不错,希望楼主好好思考一下,想不懂也没有关系,等你以后用到的时候,你会恍然大悟,
"原来这个就是传说中的动态加载!!!"