【JVM学习笔记】系统类加载器
可以通过“java.system.class.loader"属性指定系统类加载器
默认情况下,该属性值为空:
public class Test {
public static void main(String[] args) {
System.out.println(System.getProperty("java.system.class.loader"));
System.out.println(Test.class.getClassLoader());
System.out.println(ClassLoader.getSystemClassLoader());
System.out.println(ClassLoader.getSystemClassLoader().getParent());
}
}
输出结果为
null
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@1540e19d
定义一个我们自己的classloader,并尝试设置其为系统类加载器
public class MyClassLoader extends ClassLoader {
private String name; //加载器的名字
private String path; //加载路径
private final String fileType = ".class"; //class文件的扩展名
@Override
protected Class<?> findClass(String className) {
byte[] data = this.loadClassData(className);
//将字节数组转换成Class对象
return this.defineClass(className, data, 0, data.length);
}
private byte[] loadClassData(String className) {
InputStream inputStream = null;
byte[] data = null;
ByteArrayOutputStream byteArrayOutputStream = null;
try {
className = className.replace('.', '/');
inputStream = new FileInputStream(new File(path + "/" + className + fileType));
byteArrayOutputStream = new ByteArrayOutputStream();
int ch = 0;
while (-1 != (ch = inputStream.read())) {
byteArrayOutputStream.write(ch);
}
data = byteArrayOutputStream.toByteArray();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
byteArrayOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return data;
}
public MyClassLoader(String name, String path) {
// super(); //让系统类加载器成为该类加载器的父类;补充一下基础知识,如果子类没有调用父类的有参构造方法,则默认会调用无参构造方法super(),所以这一行可以注释掉
this.name = name;
this.path = path;
}
public MyClassLoader(String name, String path, ClassLoader parent) {
super(parent); //显示指定该类加载器的的父加载器
this.name = name;
this.path = path;
}
}
在控制台运行如下:
java -Djava.system.class.loader=com.learn.jvm.loader.MyClassLoader Test
运行结果

意思是缺少一个参数为ClassLoader类型的构造方法,这是在getSystemClassLoader的doc文档中有说明的

该方法的doc文档翻译如下
返回用于委托的系统类加载器。这是新ClassLoader实例的默认委托父级,通常是用于启动应用程序的类加载器。
此方法会在Java运行时启动阶段的早期被调用,此时它会创建系统类加载器并将其设置为调用线程的上下文类加载器。
默认的系统类加载器是此类的依赖于实现的实例。
如果在首次调用此方法时定义了系统属性“java.system.class.loader”,那么该属性的值将被视为将作为系统类加载器返回的类的名称。使用默认的系统类加载器加载该类,并且必须定义一个公共构造函数,该构造函数接受一个类型为ClassLoader的参数,该参数用作委托父级。然后使用此构造函数创建一个实例,并使用默认的系统类加载器作为参数。生成的类加载器被定义为系统类加载器。
如果存在安全管理器,并且调用者的类加载器不为null且调用者的类加载器与系统类加载器的祖先不同,则此方法使用RuntimePermission(“getClassLoader”)调用安全管理器的checkPermission方法)验证对系统类加载器的访问权限。如果不是,则抛出SecurityException。
于是我们增加构造方法如下:
// 新增构造方法
public MyClassLoader(ClassLoader parent) {
super(parent);
}
重新运行,结果:
D:\workspace-learn\common-learn\learn-jvm\target\classes>java -Djava.system.class.loader=com.learn.jvm.loader.MyClassLoader com.learn.jvm.loader.Test
com.learn.jvm.loader.MyClassLoader
sun.misc.Launcher$AppClassLoader@5a2264c
com.learn.jvm.loader.MyClassLoader@54624a40
sun.misc.Launcher$AppClassLoader@5a2264c
可以看出我们自定义的MyClassLoader已经称为系统类加载器,并且其父加载器为sun.misc.Launcher$AppClassLoader类的实例
【JVM学习笔记】系统类加载器的更多相关文章
- 【JVM学习笔记】类加载器
概述 类加载器用来把类加载到Java虚拟机中.从JDK1.2版本开始,类的加载过程采用父委托机制,这种机制能更好地保证Java平台的安全.在此委托机制中,除了Java虚拟机自带的根类加载器以外,其余的 ...
- Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论
Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论 创建用户自定义的类加载器 要创建用户自定义的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的f ...
- java之jvm学习笔记四(安全管理器)
java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...
- JVM学习笔记之类加载机制【八】
一.类加载时机 1.1 触发类初始化的六个场景: 加载? 1.遇到new.getstatic.putstatic或invokestatic这四条字节码指令时 如果类型没有进行过初始化,则需要先触发其初 ...
- 【JVM学习笔记】类加载过程
在Java代码中,类型的加载.连接与初始化过程都是在程序运行期间完成的:提供了更大的灵活性,增加了更多的可能性 JVM启动过程包括:加载.连接.初始化 加载:就是将class文件加载到内存.详细的说是 ...
- jvm学习笔记:类加载过程
类加载器子系统 类加载器的作用是加载class文件到内存 加载阶段->链接阶段->初始化阶段 ClassLoader只负责class文件的加载,至于是否能够运行由执行引擎判断 加载的类信息 ...
- jvm学习二:类加载器
前一节详细的聊了一下类的加载过程,本节聊一聊类的加载工具,类加载器 --- ClassLoader 本想自己写的,查资料的时候查到一篇大神的文章,写的十分详细 大家直接过去看吧http://blo ...
- JVM学习笔记——GC垃圾收集器
GC 垃圾收集器 Java 堆内存采用分代回收算法,因此 JVM 针对新生代和老年代提供了多种垃圾收集器. 1. Serial 收集器 Serial 收集器是单线程收集器,采用复制算法. 是最基本的垃 ...
- 【JVM学习笔记】扩展类加载器
扩展类加载器独有的特点,代码如下 public class Sample { } public class Test { static { System.out.println("Test ...
随机推荐
- 微信小程序 getSystemInfoSync
getSystemInfoSync 获取用户设备的相关信息 示例代码: 使用位置:在 JS文件的任意函数中使用 const res = wx.getSystemInfoSync(); console. ...
- addBack() 添加堆栈中元素集合到当前集合,一个选择性的过滤选择器。
addBack() 概述 添加堆栈中元素集合到当前集合,一个选择性的过滤选择器. 如上所述在讨论中的.end(), jQuery对象维护一个堆栈内部来跟踪匹配的元素集合的变化.当一个DOM遍历方法被调 ...
- 【转载】从头到尾彻底理解KMP
转自:http://blog.csdn.net/v_july_v/article/details/7041827 从头到尾彻底理解KMP 作者:July 时间:最初写于2011年12月,2014年7月 ...
- 在chrome开发者模式中查找你的js文件
在chrom开发者模式中按ctrl+o查找你的js文件
- 用matlab脚本语言写M文件函数时用三种方法简单实现实现DFT(离散傅里叶变换)
%用二重循环实现DFT: function xk=dt_0(xn); %define a function N=length(xn); %caculate the length of the vari ...
- CF892D—Gluttony(思维,好题)
http://codeforces.com/contest/892/problem/D D. Gluttony You are given an array a with n distinct int ...
- python中with语句的使用
引言 with 语句是从 Python 2.5 开始引入的一种与异常处理相关的功能(2.5 版本中要通过 from __future__ import with_statement 导入后才可以使用) ...
- moveDown()
这里在判断边界时,判断的是 y == HEIGHT - 1. void moveDown(){ //定义变量存放人物下方的坐标 int dx, dy; //当下方没有元素时,直接return if(y ...
- Amdahl定律和可伸缩性
性能的思考 提升性能意味着可以用更少的资源做更多的事情.但是提升性能会带来额外的复杂度,这会增加线程的安全性和活跃性上的风险. 我们渴望提升性能,但是还是要以安全为首要的.首先要保证程序能够安全正常的 ...
- 线上应用接入sentinel的第一个流控规则
sentinel接入第1个应用A以及控制台,已经上线一段时间了,本周接入了第2个应用B: 因为测试同学只有几个,没有压测团队.测试平台.. 各接口能承载的最大qps不确定 ,接入的应用暂时都没有配置规 ...