反射加载类 与 使用类加载器加载类有什么区别
方式一:反射加载
Class cl = Class.forName("classname");
方式二
使用ClassLoader
URLClassLoader loader = new URLClassLoader(urls);
Class cl = loader.loadClass("classname);
这两种方式加载类 有什么区别吗? 或者说有什么联系?
------解决方案--------------------一样的,没有区别,类装载器装载是指定装载器,forname是使用当前类装载器装载。
------解决方案--------------------一个是用在j2se项目上的,一个是用在Web项目上的,但是有时这两个都能用,用哪个都可以
------解决方案--------------------
这个视情况而定,可以一样,也可以不一样,调用者选择而已
------解决方案--------------------Class.forName是从指定的classloader中装载类,如果没有指定,也就是一个参数的时候,是从装载当前对象实例所在的classloader中装载类.
而ClassLoader的实例调用loadclass方法,是指从当前ClassLoader实例中调用类,而这个实例与装载当前所在类实例的Classloader也许不是同一个.
1.Class.forName返回的Class对象可以决定是否初始化。而ClassLoader.loadClass返回的类型绝对不会初始化,最多只会做连接操作。
2.Class.forName可以决定由哪个classLoader来请求这个类型。而ClassLoader.loadClass是用当前的classLoader去请求。
ClassLoader
bootstrap classloader(启动类加载器)
>>这个ClassLoader在JVM运行的时候加载java核心的API以满足java程序最基本的需求,其中就包括用户定义的ClassLoader
通过java程序实现的ClassLoader:
>>ExtClassLoader : 这个ClassLoader是用来加载java的扩展API的,也就是/lib/ext中的类.
>>AppClassLoader : 这个 ClassLoader是用来加载用户机器上CLASSPATH设置目录中的Class的,通常在没有指定ClassLoader的情况下,程序员自定义的类就由该ClassLoader进行加载.
程序运行:
当运行一个程序的时候,JVM启动,运行bootstrap classloader,该ClassLoader加载java核心API(ExtClassLoader和AppClassLoader也在此时被加载),然后调用ExtClassLoader加载扩展API,最后AppClassLoader加载CLASSPATH目录下定义的Class,这就是一个程序最基本的加载流程
------解决方案--------------------Class.forname(classname)会初始化这个类,可能还要加载其它相关类。
ClassLoader.loader(classname)只是加载这个类
------解决方案--------------------效果一样。至于底层如何不同,还真还细心去研究看看。
------解决方案--------------------深入了解java虚拟机
------解决方案--------------------深入java虚拟机第二版 这个书。