获得一个类所在的jar包
- ProtectionDomain pd = StringUtils.class.getProtectionDomain();
- CodeSource cs = pd.getCodeSource();
- System.out.println(cs.getLocation());
由系统类加载器所加载的类不能使用该方法来获取路径。
类的加载过程
类的加载过程分为:装载、链接、初始化。
(1)装载,查找并加载类的字节码文件。
(2)链接
验证:确保被加载类的正确性。
准备:为类的静态变量分配内存,初始化为默认值。
解析:把类中的符号引用转换为直接引用。
(3)初始化,为类的静态变量赋予正确的初始值。
在一个类加载器中,类只能初始化一次。
在堆区创建类的java.lang.class对象。class对象封装了类在方法区内的数据结构,提供了访问方法区内的数据结构和接口。
类加载器

1)Bootstrap ClassLoader
负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类
2)Extension ClassLoader
负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包
3)App ClassLoader(system class loader)
负责记载classpath中指定的jar包及目录中class,java应用的类都是由它完成加载的。通过ClassLoader.getSystemClassLoader()来获取它。
4)Custom ClassLoader
属于应用程序根据自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现ClassLoader。
除了引导类加载器之外,所有的类加载器都有一个父类加载器。
系统类加载器的父类加载器是扩展类加载器,扩展类加载器的父类加载器是引导类加载器。
对于Custom ClassLoader,其父类加载器是加载此类加载器java类的类加载器。类加载器java类也是由类加载器来加载的。一般Custom ClassLoader的父类加载器是系统类加载器。
每个java类都维护着一个指向加载该类的类加载器的引用。
类加载器的代理模式
线程上下文类加载器
Custom ClassLoader
方法 | 说明 |
---|---|
getParent() | 返回该类加载器的父类加载器。 |
loadClass(String
name) |
加载名称为 name 的类,返回的结果是 java.lang.Class 类的实例。 |
findClass(String
name) |
查找名称为 name 的类,返回的结果是 java.lang.Class 类的实例。 |
findLoadedClass(String
name) |
查找名称为 name 的已经被加载过的类,返回的结果是 java.lang.Class 类的实例。 |
defineClass(String
name, byte[] b, int off, int len) |
把字节数组 b 中的内容转换成
Java 类,返回的结果是 java.lang.Class 类的实例。这个方法被声明为 final 的。 |
resolveClass(Class<?>
c) | 链接指定的 Java 类。 |