java类加载器和类反射使用示例

一、一个命令对应一个进程。

当我们启动一个Java程序,即启动一个main方法时,都将启动一个Java虚拟机进程,不管这个进程有多么复杂。而不同的JVM进程之间是不会相互影响的。这也就是为什么说,Java程序只有一个入口——main方法,让虚拟机调用。而两个mian方法,对应的是2个JVM进程,启动的是两个不同的类加载器,操作的实际上是不同的类。故而不会互相影响。

二、类加载。

当我们使用一个类,如果这个类还未加载到内存中,系统会通过加载、连接、初始化对类进行初始化。

1、类加载:指的是将类的class文件读入JVM,并为之创建一个Class对象。

2、类连接:指的是把类的二进制数据合并到JRE中,这又分为3个阶段:

a)、校验:检查载入Class文件数据的正确性。

b)、准备:给类的静态变量分配存储空间,并进行默认初始化。

c)、解析:将类的二进制数据中的符号引用替换成直接引用。

3、初始化:对类的静态变量、静态初始化块进行初始化。

(注意:一个final类型的静态属性,如果在编译时已经得到了属性值,那么调用该属性时,不会导致该类初始化,因为这个相当于使用常量;

使用ClassLoader()方法,只是加载该类,并未初始化。)

三、类加载器。

类加载器就是负责将.class文件加载到内存中,并为之生成对应的java.lang.Class对象,它负责加载所有的类,而一旦一个类被加载入JVM中,就不会被再次载入了。

在Java中,一个类用其全限定类名(即包名+类名)作为标识。

而在JVM中,一个类用其全限定类名和其类加载器作为标识。

JVM运行时会产生3个ClassLoader,分别为:BootstrapClassLoader(根类加载器)、ExtClassLoader(扩展类加载器)和AppClassLoader(系统类加载器)。UML结构如下:

其中,BootstrapClassLoader负责加载JRE的核心类库,它不是ClassLoader的子类,使用C++编写,因此我们在Java中看不到它,通过其子类的getParent()方法获取时,将返回null。BootstrapClassLoader负责装载JRE目标下的rt.jar、charsets.jar等Java核心类库。

如图可知,ExtClassLoader和AppClassLoader为ClassLoader的子类。在API中看不到它们,他们位于rt.jar文件中。全限定类名分别为:

sun.misc.Launcher$ExtClassLoader 和 sun.misc.Launcher$AppClassLoader.

其中,ExtClassLoader负责装载JRE扩展目录ext中JAR包,而AppClassLoader负责装载Classpath路径下的类包。

测试如下:

代码如下:

package com.stopTalking.crazy;
public class TestClassLoader {
public static void main(String[] args) {
//获取当前线程的类装载器 
ClassLoader loader = Thread.currentThread().getContextClassLoader(); 
//获取System类的类装载器 
ClassLoader loader1 = System.class.getClassLoader(); 
//获取本类TestClassLoader的类装载器loader2 
ClassLoader loader2 = TestClassLoader.class.getClassLoader(); 
//获取loader2的父类 
ClassLoader loader3 = loader2.getParent(); 
//获取loader2的父类的父类 
ClassLoader loader4 = loader3.getParent(); 
System.out.println(loader); 
System.out.println(loader1); 
System.out.println(loader2); 
System.out.println(loader3); 
System.out.println(loader4); 

}

控制台输出:

代码如下:

//当前线程类获取的类加载器是AppClassLoader
sun.misc.Launcher$AppClassLoader@6b97fd
//System类为根装载器加载,java中访问不到,所以为null
null
//本类的类加载器当然也是AppClassLoader
sun.misc.Launcher$AppClassLoader@6b97fd
sun.misc.Launcher$ExtClassLoader@1c78e57
null

(0)

相关推荐

  • java基础学习笔记之类加载器

    类加载器 java类加载器就是在运行时在JVM中动态地加载所需的类,java类加载器基于三个机制:委托,可见,单一. 把classpath下的那些.class文件加载进内存,处理后成为字节码,这些工作是类加载器做的. 委托机制指的是将加载类的请求传递给父加载器,如果父加载器找不到或者不能加载这个类,那么再加载他. 可见性机制指的是父加载器加载的类都能被子加载器看见,但是子加载器加载的类父加载器是看不见的. 单一性机制指的是一个类只能被同一种加载器加载一次. 默认类加载器 系统默认三个类加载器:

  • classloader类加载器_基于java类的加载方式详解

    基础概念 Classloader 类加载器,用来加载 Java 类到 Java 虚拟机中.与普通程序不同的是.Java程序(class文件)并不是本地的可执行程序.当运行Java程序时,首先运行JVM(Java虚拟机),然后再把Java class加载到JVM里头运行,负责加载Java class的这部分就叫做Class Loader. JVM本身包含了一个ClassLoader称为Bootstrap ClassLoader,和JVM一样,BootstrapClassLoader是用本地代码实现

  • java 详解类加载器的双亲委派及打破双亲委派

    java 详解类加载器的双亲委派及打破双亲委派 一般的场景中使用Java默认的类加载器即可,但有时为了达到某种目的又不得不实现自己的类加载器,例如为了达到类库的互相隔离,例如为了达到热部署重加载功能.这时就需要自己定义类加载器,每个类加载器加载各自的类库资源,以此达到资源隔离效果.在对资源的加载上可以沿用双亲委派机制,也可以打破双亲委派机制. 一.沿用双亲委派机制自定义类加载器很简单,只需继承ClassLoader类并重写findClass方法即可.如下例子: ①先定义一个待加载的类Test,它

  • 深入解析Java中的Class Loader类加载器

    类加载的过程 类加载器的主要工作就是把类文件加载到JVM中.如下图所示,其过程分为三步: 1.加载:定位要加载的类文件,并将其字节流装载到JVM中: 2.链接:给要加载的类分配最基本的内存结构保存其信息,比如属性,方法以及引用的类.在该阶段,该类还处于不可用状态: (1)验证:对加载的字节流进行验证,比如格式上的,安全方面的: (2)内存分配:为该类准备内存空间来表示其属性,方法以及引用的类: (3)解析:加载该类所引用的其它类,比如父类,实现的接口等. 3.初始化:对类变量进行赋值. 类加载器

  • JAVA提高第七篇 类加载器解析

    今天我们学习类加载器,关于类加载器其实和JVM有很大关系,在这里这篇文章只是简单的介绍下类加载器,后面学习到JVM的时候还会详细讲到类加载器,本文分为下面几个小节讲解: 一.认识类加载器 1.什么是类加载器? 所谓的类加载器可以从其作用来理解,其功能就是将classpath目录下.class文件,加载到内存中来进行一些处理,处理完的结果就是一些字节码.那是谁把这些class类加载到内存中来的呢?就是类加载器. 2.JVM中默认的类加载器有哪些? java虚拟机中可以安装多个类加载器,系统默认三个

  • java 类加载与自定义类加载器详解

    类加载 所有类加载器,都是ClassLoader的子类. 类加载器永远以.class运行的目录为准. 读取classpath根目录下的文件有以下几种方式: 1 在Java项目中可以通过以下方式获取classspath下的文件: public void abc(){ //每一种读取方法,使用某个类获取Appclassloader ClassLoader cl = ReadFile.class.getClassLoader(); URL url = cl.getResource("a.txt&quo

  • Java中的类加载器_动力节点Java学院整理

    从java的动态性到类加载机制 Java是一种动态语言.那么怎样理解这个"动态"呢?或者说一门语言具备了什么特性,才能称之为动态语言呢?对于java,我是这样理解的. JVM(java虚拟机)执行的不是本地机器码指令,而是执行一种称之为字节码的指令(存在于class文件中).这就要求虚拟机在真正执行字节码之前,先把相关的class文件加载到内存中.虚拟机不是一次性加载所有需要的class文件,因为它在执行的时候根本不会知道以后会用到哪些class文件.它是每用到一个类,就会在运行时&q

  • java类加载器和类反射使用示例

    一.一个命令对应一个进程. 当我们启动一个Java程序,即启动一个main方法时,都将启动一个Java虚拟机进程,不管这个进程有多么复杂.而不同的JVM进程之间是不会相互影响的.这也就是为什么说,Java程序只有一个入口--main方法,让虚拟机调用.而两个mian方法,对应的是2个JVM进程,启动的是两个不同的类加载器,操作的实际上是不同的类.故而不会互相影响. 二.类加载. 当我们使用一个类,如果这个类还未加载到内存中,系统会通过加载.连接.初始化对类进行初始化. 1.类加载:指的是将类的c

  • Java通过自定义类加载器实现类隔离

    目录 前言 类隔离是什么 使用场景 解决方案 重写findClass 重写loadClass 总结 前言 由于微服务的快速迭代.持续集成等特性,越来越多的团队更倾向于它.但是也体现出了一些问题,比如在基础设施建设过程中,需要把通用功能下沉,把现有大而全的基础设施按领域拆分,考虑需要兼容现有生产服务,会产生不同的依赖版本,有时不注意就可以引发问题.比如本文遇到的依赖包版本冲突问题,以及如何利用类隔离技术解决的分析. 类隔离是什么 类隔离是一种通过类加载器实现加载所需类的实现方式,使得不同版本类间隔

  • Java类加载器ClassLoader用法解析

    这篇文章主要介绍了Java类加载器ClassLoader用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 正文 当程序主动使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载.连接.初始化3个步骤来对该类进行初始化.如果没有意外,JVM将会连续完成3个步骤,所以有时也把这个3个步骤统称为类加载或类初始化. 一.类加载过程 1.加载 加载指的是将类的class文件读入到内存,并为之创建一个java.lang.Class对象,也就是说

  • 浅谈JAVA 类加载器

    类加载机制 类加载器负责加载所有的类,系统为所有被载入内存中的类生成一个 java.lang.Class 实例.一旦一个类被载入 JVM 中,同个类就不会被再次载入了.现在的问题是,怎么样才算"同一个类"? 正如一个对象有一个唯一的标识一样,一个载入 JVM 中的类也有一个唯一的标识.在 Java 中,一个类用其全限定类名(包括包名和类名)作为标识:但在 JVM 中,一个类用其全限定类名和其类加载器作为唯一标识.例如,如果在 pg 的包中有一个名为 Person 的类,被类加载器 Cl

  • 详解Java类加载器与双亲委派机制

    目录 引子 了解.class文件 类加载的过程 类加载器 与 双亲委派机制 ClassLoader 自定义类加载器 编写一个自定义的类加载器 为什么我们这边要打破双亲委派机制 自定义类加载器时,如何打破双亲委派机制 SPI机制 与 线程上下文类加载器 JDBC Tomcat SpringBoot Starter 尾语 引子 大家想必都有过平时开发springboot 项目的时候稍微改动一点代码,就得重启,就很烦 网上一般介绍 2种方式 spring-boot-devtools,或者通过JRebe

  • Java类加载器与双亲委派机制和线程上下文类加载器专项解读分析

    目录 一.类加载器 1.启动类加载器 2.拓展类加载器 3.应用类加载器 4.类的命名空间 二.双亲委派机制 1.类加载机制流程 2.类加载器加载顺序 3.双亲委派机制流程 4.源码分析 5.双亲委派机制优缺点 三.线程上下文类加载器 1.线程上下文类加载器(Context Classloader) 2.ServiceLoader 四.自定义类加载器 一.类加载器 类加载器就是根据类的二进制名(binary name)读取java编译器编译好的字节码文件(.class文件),并且转化生成一个ja

  • Java类加载器和类加载机制实例分析

    本文实例讲述了Java类加载器和类加载机制.分享给大家供大家参考,具体如下: 一 点睛 1 类加载器负责将.class文件(可能在磁盘上,也可能在网络上)加载到内存中,并为之生成对应的java.lang.Class对象. 2 当JVM启动时,会形成由三个类加载器组成的初始类加载器层次结构: Bootstrap ClassLoader:根类加载器. Extension ClassLoader:扩展类加载器. System ClassLoader:系统类加载器. 3 JVM的类加载机制主要有如下三种

  • 源码解析Java类加载器

    参考内容: 深入理解Java虚拟机(JVM高级特性与最佳实践) --周志明老师 尚硅谷深入理解JVM教学视频--宋红康老师 我们都知道Java的类加载器结构为下图所示(JDK8及之前,JDK9进行了模块化): 关于三层类加载器.双亲委派机制,本文不再板书,读者可自行百度. 那么在JDK的源码中,三层结构的具体实现是怎么样的呢? Bootstrap ClassLoader(引导类加载器) 引导类加载器是由C++实现的,并非Java代码实现,所以在Java代码中是无法获取到该类加载器的. 一般大家都

  • Java框架设计灵魂之反射的示例详解

    目录 获取Class对象的方式 Class对象功能 获取成员变量们 获取构造方法们 获取成员方法们 获取全类名 Field:成员变量 Constructor:构造方法 Method:方法对象 案例 框架:半成品软件.可以在框架的基础上进行软件开发,简化编码. 反射就是把Java类中的各个成员映射成一个个的Java对象. 即在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法: 对于任意一个对象,都能调用它的任意一个方法和属性. 这种动态获取信息及动态调用对象方法的功能叫Java的反射机

  • Java类加载器ClassLoader的使用详解

    目录 BootstrapClassLoader ExtClassLoader AppClassLoader 类加载器的具体实现在哪里 类加载器的初始化时机 如何进行的类加载 Loader.getResource(resourceName) 调用获取资源方法的一些常见问题 BootstrapClassLoader 加载范围(根据系统参数): System.getProperty("sun.boot.class.path"); 负责加载核心类库,以我的本地的环境来展示获取的内容: D:\d

随机推荐