84669인 학습
152542인 학습
20005인 학습
5487인 학습
7821인 학습
359900인 학습
3350인 학습
180660인 학습
48569인 학습
18603인 학습
40936인 학습
1549인 학습
1183인 학습
32909인 학습
看到网上这么说:
双亲委派机制描述某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。
首先将加载任务委托给父类加载器,依次递归这句话的意思是所有类都是由Object类的记载器加载的吗?
光阴似箭催人老,日月如移越少年。
Java 虚拟机的第一个类加载器是 Bootstrap,这个加载器是嵌套在 Java 虚拟机内核里面,它是用 C++ 写的二进制代码(不是字节码)。
使用委托机制,会递归的向父类查找,也就是首选用 Bootstrap 尝试加载,如果找不到再向下。防止内存中出现两份类的字节码。
你误解了类和类加载器。
当类记载的时候,首先用当前线程的类加载器去加载线程中的第一个类,比如这个类是 ClassA,类加载器是 ClassLoaderA。
如果 ClassA 引用了 ClassB,则系统会使用 ClassLoaderA 去加载 ClassB。
现在有了 2 个类(简化版,其实不止是 2 个类)。
我们考虑一种情况,ClassX 和 ClassY 已经在内存中加载,他们都引用了 ClassZ,那么 ClassZ 由谁加载呢?
很显然按照上面描述的加载步骤会出现 2 份 ClassZ:ClassX 加载一次,ClassY 又加载一次。因为 ClassY 不知道 ClassX 已经加载过了。
如何解决这个问题呢,就是向父类递归查找。
具体步骤就是,先从 BootstrapClassLoader 查找,如果 BootstrapClassLoader 加载了这个类,就返回,如果 BootstrapClassLoader 没有加载过这个类,则继续查找,直到找到这个类。如果一直找到了本线程的类加载器都没有找到,说明这个类还没有加载,则使用当前线程的加载器加载。可以使用getContextClassLoader()获得当前线程的类加载器。
getContextClassLoader()
Java中有两类类加载器:系统类加载器和用户自定义类加载器。
系统类加载器都会有加载路径的限定,比如Bootstrap Class Loader在JDK1.6下,通过System.getProperty("sun.boot.class.path")可以得到类加载路径
Bootstrap Class Loader
System.getProperty("sun.boot.class.path")
JAVA_HOME\jre6\lib\resources.jar; JAVA_HOME\Java\jre6\lib\rt.jar; JAVA_HOME\jre6\lib\sunrsasign.jar; JAVA_HOME\jre6\lib\jsse.jar;JAVA_HOME\jre6\lib\jce.jar; JAVA_HOME\jre6\lib\charsets.jar; JAVA_HOME\jre6\lib\modules\jdk.boot.jar; JAVA_HOME\jre6\classes
这些路径下的class是由Bootstrap负责,其它路径下的class的递归到Bootstrap下也是找不到class文件,就会由下一级类加载器去相应的路径去加载。
Bootstrap
楼上说得对,建议看看jvm相关书籍,详细了解一下.
Java 虚拟机的第一个类加载器是 Bootstrap,这个加载器是嵌套在 Java 虚拟机内核里面,它是用 C++ 写的二进制代码(不是字节码)。
使用委托机制,会递归的向父类查找,也就是首选用 Bootstrap 尝试加载,如果找不到再向下。防止内存中出现两份类的字节码。
你误解了类和类加载器。
当类记载的时候,首先用当前线程的类加载器去加载线程中的第一个类,比如这个类是 ClassA,类加载器是 ClassLoaderA。
如果 ClassA 引用了 ClassB,则系统会使用 ClassLoaderA 去加载 ClassB。
现在有了 2 个类(简化版,其实不止是 2 个类)。
我们考虑一种情况,ClassX 和 ClassY 已经在内存中加载,他们都引用了 ClassZ,那么 ClassZ 由谁加载呢?
很显然按照上面描述的加载步骤会出现 2 份 ClassZ:ClassX 加载一次,ClassY 又加载一次。因为 ClassY 不知道 ClassX 已经加载过了。
如何解决这个问题呢,就是向父类递归查找。
具体步骤就是,先从 BootstrapClassLoader 查找,如果 BootstrapClassLoader 加载了这个类,就返回,如果 BootstrapClassLoader 没有加载过这个类,则继续查找,直到找到这个类。如果一直找到了本线程的类加载器都没有找到,说明这个类还没有加载,则使用当前线程的加载器加载。可以使用
getContextClassLoader()
获得当前线程的类加载器。Java中有两类类加载器:系统类加载器和用户自定义类加载器。
系统类加载器都会有加载路径的限定,比如
Bootstrap Class Loader
在JDK1.6下,通过System.getProperty("sun.boot.class.path")
可以得到类加载路径这些路径下的class是由
Bootstrap
负责,其它路径下的class的递归到Bootstrap
下也是找不到class文件,就会由下一级类加载器去相应的路径去加载。楼上说得对,建议看看jvm相关书籍,详细了解一下.