If the system property "java.system.class.loader" is defined
* when this method is first invoked then the value of that property is
* taken to be the name of a class that will be returned as the system
* class loader. The class is loaded using the default system class loader
* and must define a public constructor that takes a single parameter of
* type ClassLoader which is used as the delegation parent. An
* instance is then created using this constructor with the default system
* class loader as the parameter. The resulting class loader is defined
* to be the system class loader.
* 如果设定了java.system.class.loader那么这个方法返回的就是java.system.class.loader设定的类加载器。这个类被系统类加载器加载,并且
* 定义一个公共的构造方法,接受一个ClassLoader参数用作为委托的双亲,用默认系统类类加载器作为构造器的参数,就会创造一个实例 ,所得到的就是系统类加载器
*/
//返回系统类加载器
@CallerSensitive
public static ClassLoader getSystemClassLoader() {
initSystemClassLoader();
if (scl == null) {
return null;
}
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkClassLoaderPermission(scl, Reflection.getCallerClass());
}
return scl;
}
```
> getParent方法:
```java
/**
* Returns the parent class loader for delegation. Some implementations may
* use null to represent the bootstrap class loader. This method
* will return null in such implementations if this class loader's
* parent is the bootstrap class loader.
* 返回父加载器用于委托,有些实现返回null用来表示根类加载器,如果一个类的父加载器是根加载器,那么这个方法将会返回null
*/
public final ClassLoader getParent() {
if (parent == null)
return null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// Check access to the parent class loader
// If the caller's class loader is same as this class loader,
// permission check is performed.
checkClassLoaderPermission(parent, Reflection.getCallerClass());
}
return parent;
}
```
> parent 变量是ClassLoader的成员变量:
```java
// The parent class loader for delegation
// Note: VM hardcoded the offset of this field, thus all new fields
// must be added *after* it.
用于委托的双亲加载器,JVM将这个变量的偏移量进行了硬编码,,这样新的变量就要加载这个变量的后边
private final ClassLoader parent;
```
> 下一例子:
如何通过一个给定的字节码的路径来把相应的资源信息打印出来
```java
public class MyTest14 {
public static void main(String[] args) throws IOException {
//Thread.currentThread():或取到当前执行的线程一个引用
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();//通常用于启动应用的应用类加载器
String resourceName = "com/twodragonlake/jvm/classloader/MyTest13.class";//包名
/*
Finds all the resources with the given name. A resource is some data
(images, audio, text, etc) that can be accessed by class code in a way
that is independent of the location of the code.
返回给定名字所有的资源,资源可以是(图片,音频,文本,等)可以被class字节码以一种与字节码位置无关的方式去访问,
classLoader.getResources(resourceName){....}
*/
Enumerationurls = classLoader.getResources(resourceName);//找到给定名字的所有资源
while(urls.hasMoreElements()){
System.out.println(urls.nextElement());
}
System.out.println("----------------");
Class> clazz = String.class;
System.out.println(clazz.getClassLoader());//自定义的类有系统类加载器加载
System.out.println("----------------");
clazz = MyTest14.class;
System.out.println(clazz.getClassLoader()); //由根类加载器加载 因为系统类加载器的加载目录包含rt目录
}
}
```
> 运行结果
```java
file:/E:/Study/intelIde/jvm_lecture/out/production/classes/com/twodragonlake/jvm/classloader/MyTest13.class
----------------
null
----------------
sun.misc.Launcher$AppClassLoader@18b4aac2
```
> **获取`ClassLoader`的方式**
获得当前类的`ClassLoader`:
`class.getClassLoader()`;
获取当前线程上下文的`ClassLoader`:
`Thread.currentThread().getContextClassLoader();`
获得系统的`ClassLoader`:
`ClassLoader.getSystemClassLoader()`
获得调用者的`ClassLoader`:
`DriverManager.getCallerClassLoader();`
类加载器不是用来加载对象的,是加载和对象对应的类。
class对象对应的是类本身
### 类加载器的双亲委托机制
![不同的类加载器作用与加载动作分析02.png][2]
如果感觉本篇看着还不是太懂可以看下篇博客:[不同的类加载器作用与加载动作分析](https://www.cnblogs.com/webor2006/p/9029910.html),这篇小编就先不进行复制了。直接点击链接就可以跳到原文。
附:[参考原文1](https://ceaser.wang/2018/10/04/jvm%E5%8E%9F%E7%90%86%EF%BC%888%EF%BC%89%E4%B8%8D%E5%90%8C%E7%9A%84%E7%B1%BB%E5%8A%A0%E8%BD%BD%E5%99%A8%E4%B8%8E%E5%8A%A0%E8%BD%BD%E4%B8%8E%E5%8A%A0%E8%BD%BD%E5%8A%A8%E4%BD%9C%E5%88%86%E6%9E%90/),[参考原文2](https://www.cnblogs.com/webor2006/p/9029910.html)。
[1]: https://lilinchao.com/usr/uploads/2019/12/4152142786.png
[2]: https://lilinchao.com/usr/uploads/2019/12/4238738204.png