前言 在上一篇讲述了入门和实操https://cloud.tencent.com/developer/article/2360594 本章节使用字节码和byte-buddy来玩 通过字节码对方法增强 新建一个...} } }).start(); } } PreMainAgent 重新 install,然后在运行效果如下图所示: 使用 byte-buddy...); } public static void buttyBuddyDemo(String agentOps, Instrumentation inst) { // Byte-Buddy...System.out.println("=========agentmain方法执行========"); simpleDemo(agentOps, inst); //transform是会对尚未加载的类进行增加代理层...,这里是已经运行中的jvm,所以类以及被加载了 //必须主动调用retransformClasses让jvm再对运行中的类进行加上代理层 //下一次执行的时候, 要重新读取
类加载机制 所谓类加载机制就是JVM虚拟机把Class文件加载到内存,并对数据进行校验,转换解析和初始化,形成虚拟机可以直接使用的Jav类型,即Java.lang.Class。 2....JVM初始化步骤 1、假如这个类还没有被加载和链接,则程序先加载并链接该类 2、假如该类的直接父类还没有被初始化,则先初始化其直接父类 3、假如类中有初始化语句,则系统依次执行这些初始化语句 类初始化时机...clinit 方法和init 方法的区别 init和clinit方法执行时机不同 init是对象构造器方法,也就是说在程序执行new 一个对象调用该对象类的 constructor 方法时才会执行init...在Java中,一个类用其全限定类名(包括包名和类名)作为标识;但在JVM中,一个类用其全限定类名和其类加载器作为其唯一标识。...这意味着两个类加载器加载的同名类:(Person.pg.kl)和(Person.pg.kl2)是不同的、它们所加载的类也是完全不同、互不兼容的。
希望大家看了之后更能理解JVM的工作原理和java类的生产过程(类加载的过程); 类从被加载到虚拟机类存中开始,到被卸载出内存为止,它的整个生命周期包括 加载 → 验证 → 准备 → 解析 → 初始化 ...: 1.先检查此类是否被加载过,若没有加载则调用父加载器的loadClass()方法, 2.若父加载器为空,则默认使用启动类加载器作为父加载器, 3.若父类加载失败,会抛出一个异常,然后再调用自己的findClass...()方法来进行加载; 结合第一步加载可以这么理解, 1.首先要启动→ 启动类加载器,这时会调用启动类加载器的父加载器,但由于启动类加载器时所有类的父加载器, 所以其父加载器为空(相当于Object...是所有类的父类,这种感脚~),然后它就会调用自己的findClass方法来自启动加载 ; 2.标准扩展类加载器启动时就会借助其父类 启动类加载器 作为父加载器 来启动了; 3.系统类加载器启动时就会借助其父类...3.类方法解析; 4.接口方法解析; 此部分内容涉及 invokedynamic指令,静态、动态语音调用 不做展开 如果解析到代码内容有问题,解析不通过将会抛出异常!
1、类与类加载器 类加载器只用于实现类的加载动作。 但对于任意一个类,都必须由加载它的类加载器和这个类本身一起共同确立其在Java虚拟机中的唯一性,每 一个类加载器,都拥有一个独立的类名称空间。 ?...) { return super.loadClass(name); } byte...[] b = new byte[is.available()]; is.read(b); //从流中转化类的实例...} } catch (ClassNotFoundException e) { // 如果父类加载器抛出...由于双亲委派模型在JDK 1.2之后才被引入,但是类加载器的概念和抽象类 java.lang.ClassLoader则在Java的第一个版本中就已经存在,为了向下兼容旧代码,所以无法以技术手段避免loadClass
希望大家看了之后更能理解JVM的工作原理和java类的生产过程(类加载的过程); 类从被加载到虚拟机类存中开始,到被卸载出内存为止,它的整个生命周期包括 加载 → 验证 → 准备 → 解析 → 初始化 ...: 1.先检查此类是否被加载过,若没有加载则调用父加载器的loadClass()方法, 2.若父加载器为空,则默认使用启动类加载器作为父加载器, 3.若父类加载失败,会抛出一个异常,然后再调用自己的findClass...()方法来进行加载; 结合第一步加载可以这么理解, 1.首先要启动→ 启动类加载器,这时会调用启动类加载器的父加载器,但由于启动类加载器时所有类的父加载器, 所以其父加载器为空(相当于Object...是所有类的父类,这种感脚~),然后它就会调用自己的findClass方法来自启动加载 ; 2.标准扩展类加载器启动时就会借助其父类 启动类加载器 作为父加载器 来启动了; 3.系统类加载器启动时就会借助其父类...2.字段解析; 3.类方法解析; 4.接口方法解析; 此部分内容涉及 invokedynamic指令,静态、动态语音调用 不做展开 如果解析到代码内容有问题,解析不通过将会抛出异常!
事实上,虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验,转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型的过程就是虚拟机的类加载机制。...(类的五个加载过程) 二、类的加载时机 1.类的生命周期 类从被加载到虚拟机内存中开始,到卸载出内存为止,整个生命周期包括加载、验证、准备、解析、初始化、使用和卸载。...另外,类的加载阶段涉及类加载器和双亲委派模型等知识点,此处将另起新随笔详细介绍,在本文就不多费笔墨了。...5.初始化 类初始化阶段是类加载过程的最后一步。在前面的类加载过程中,除了在加载阶段用户应用程序可以通过自定义类加载器参与之外,其余动作完全由虚拟机主导和控制。...举个例子: static { i = 5; System.out.println(i);//在此处抛出错误:非法的向前引用 } public static int i = 0; 3.多线程环境下的类构造器
02 类加载与类加载器 类加载: 类加载的过程就是将Class文件中描述的各种信息加载到虚拟机中,供程序后期运行和使用的。...5、初始化 是类加载生命周期的最后一个过程,执行类中定义的java程序代码 类加载器: 在前面的类加载过程中,大部分动作都是完全由虚拟机主导和控制的。...类加载器和这个类本身确定了其在java虚拟机中的唯一性,每一个类加载器都有一个独立的类命名空间,也就意味着,如果比较两个类是否相等,只有在这两个类是由同一个类加载器加载的前提下才有意义,否则,即使这两个类来源于同一个...Class文件,被同一个虚拟机加载,只要加载他们的类加载器不同,那么这两个类就注定不相同。...和Extention Class Loader加载,在实际应用中,可以是网络中传递过来的加密字节流,抑或着是实现脚本的热部署操作。
(先有个C才有的JAVA,底层还是通过C和C++来实现的),核心的重点是谁都不能少,少了无法存活。...用户应用程序class-path 或者java命令运行时参数 -cp(开发人员写的代码,对应类存放在哪里,JAVA是怎么知道的,为什么用eclipse和idea右键可以直接跑了,其实就是在底层指定目录地址...jcmd查看的 java.class.path 里面加载了很多对应的路径,其中就包括idea里面对应这个类的路径。 ? ③ 类不会重复加载 类的唯一性:同一个类加载器,类名一样,代表是同一个类。...,输出类加载和卸载的日志信息。...首先不会自己去尝试加载类,而是把这个请求委派给父加载器去完成,每一个层次的加载器都是如此,因此所有的类加载请求都会传给上层的启动类加载器。
布局和内存无关。直接引用:是指向目标的指针,偏移量或者能够直接定位的句柄。该引用是和内存中的布局有关的,并且一定加载进来的。...正如一个对象有一个唯一的标识一样,一个载入JVM的类也有一个唯一的标识。在Java中,一个类用其全限定类名(包括包名和类名)作为标识;但在JVM中,一个类用其全限定类名和其类加载器作为其唯一标识。...这意味着两个类加载器加载的同名类:(Person.pg.kl)和(Person.pg.kl2)是不同的、它们所加载的类也是完全不同、互不兼容的。...或者CLASSPATH换将变量所指定的JAR包和类路径。...当前类加载器尝试寻找Class文件,如果找到则执行第6步,如果找不到则执行第7步。 从文件中载入Class,成功后跳至第8步。 抛出ClassNotFountException异常。
A: initialized = true B: initialized = false C: 编译错误 D: 以上答案都是错的 Explain 程序执行的时候,App Classloader 会首先加载...private static boolean initialized = false; CASE 1 我们都知道,static块会在类加载的时候初始化,那么下一步会执行到Thread thread =...和上一个是一样的,为什么就可以成功呢?...那么就会开始等待主线程初始化完成,这个时候,根据classloader加载类的执行顺序,在#16就会开始等待,那么主类无法初始化完成,造成相互等待现相。...(匿名/Lambda)和主类初始化中相互依赖的对象
以下是OSGi的类加载器架构和特性:模块化构建: OSGi允许将应用程序划分为多个独立的模块,每个模块都有自己的类和资源。这种模块化的构建方式可以将应用程序划分为更小的可维护和可重用的部分。...类加载器层次结构: OSGi引入了类加载器层次结构,包括了系统类加载器、扩展类加载器和模块类加载器。每个模块都有自己独立的类加载器,它只加载属于模块的类和资源,并且可以隔离不同模块之间的类和资源。...模块隔离性: OSGi的类加载器架构提供了模块之间的隔离性。每个模块都有自己独立的类加载器,它只加载属于模块的类和资源。这种隔离性可以防止模块之间的类冲突和版本冲突。...OSGi类加载器相比其他类加载器的优势模块化架构: OSGi的类加载器架构是为模块化设计的,使得应用程序可以按需加载和管理模块。与传统的类加载器相比,它更适合构建大型和复杂的应用程序。...模块隔离性: OSGi的类加载器架构提供了模块之间的隔离性。每个模块有自己独立的类加载器,它只加载属于模块的类和资源。这种隔离性可以防止模块之间的类冲突和版本冲突,提高了应用程序的稳定性和可靠性。
类加载的结论和代码演示 顺序: 父类静态属性 (可以是对象) 和静态代码块,看其在类中的先后顺序 子类静态属性和静态代码块 ,看其在类中的先后顺序 父类非静态属性和非静态代码块 ,看其在类中的先后顺序...找到其父类,从父类开始加载,Sub 类继承了 Root 类,所以先加载 Root 类的静态属性: 加载 Root 类,静态属性和代码块随着类的加载而加载 public static StaticAttribute...,输出第五行 然后是 new 对象,所以再回到父类中加载非静态的属性、代码块(属性和代码块按照再类中写的先后顺序加载),最后再加载父类的构造方法。 ...回单 Main 方法中继续执行 System.out.println(); 复制代码 换行之后,我们又 new 了一个对象,这个时候重复 3 和 4 过程就行,因为类只需要加载一次,静态属性和代码块是随类的加载而加载的...找到其父类,从父类开始加载,其父类为 Root 类,加载 Root 类,静态属性和代码块随着类的加载而加载,此时 Root 类中第一行代码为 public static Root s = new Root
Class类文件的结构 任何一个Class文件都对应着唯一一个类或接口的定义信息,但反过来说,类或接口并不一定都得定义在文件里(类和接口也可以用反射的方式通过类加载器直接生成) Class文件时一组以...加载、验证、准备、初始化和卸载这 5 个阶段的顺序是确定的,类的加载过程必须按照这种顺序按部就班地开始(注意是“开始”,而不是“进行”或“完成”),而解析阶段则不一定:它在某些情况下可以在初始化后再开始...类加载的过程 类加载过程包括 5 个阶段:加载、验证、准备、解析和初始化。...“数组类”与“非数组类”加载情况的不同 非数组类由加载器来进行加载 数组类由于没有字节流,由jvm直接创建,如果数组中的对象是引用类,递归采用加载器进行加载 注意事项 虚拟机规范未规定 Class 对象的存储位置...)一个阶段,如果运行的全部代码(包括自己编写的以及第三方包中的代码)都已经被反复使用和验证过,那么在实施阶段就可以使用-Xverify:none来关闭大部分类的验证过程,以缩短虚拟机类加载的时间 准备
---- 上一篇文章 自定义ClassLoader和双亲委派机制 讲述了 JVM 中的类的加载机制,Android 也是类 JVM 虚拟机那么它的类加载机制是什么呢,我们来探究一下(PS:文章源码为 Android5.1...前言 Android 的 Dalvik 虚拟机和 Java 虚拟机的运行原理相同都是将对应的 java 类加载在内存中运行。...而 Java 虚拟机是加载 class 文件,也可以将一段二进制流通过 defineClass 方法生产 Class 进行加载(PS: 自定义ClassLoader和双亲委派机制 文章后面的自定义类加载器就是通过这种方式实现的...dex 在 Android 中的加载和 class 在 jvm 中的相同都是基于双亲委派模型,都是调用ClassLoader 的 loadClass 方法加载类。...Android 系统中有两个类加载器分别为 PathClassLoader 和 DexclassLoader。
数组类和非数组类的类加载是不同的,具体情况如下: 非数组类:是由类加载器来定成。...类加载过程的注意点 加载阶段和链接阶段是交叉的 类加载的过程中每个步骤的开始顺序都有严格限制,但每个步骤的结束顺序没有限制。...印证【加载和验证】是交叉进行的: 1.加载开始前,⼆进制字节流还没进⽅法区,⽽加载完成后,⼆进制字节流 已经存⼊⽅法区 2....4.负责加载扩展类加载器和系统应用类加载器,并为他们指定父加载器 5.出于安全考虑,该加载器只负责加载java,javax,sun等开头的类 扩展类加载器 是java语言编写,派生于ClassLoader...因为Java中提供的默认ClassLoader,只加载指定目录下的jar和class,如果我们想加载其它位置的类或jar时,就只能自定义一个ClassLoader类了。
,这篇文章主要是加深一些对类实例化和类加载的认识。...> defineClass(String name, byte[] b, int off, int len)方法用于指定全类名和字节码字节数组去定义一个类,我们再次看下loadClass()的源码:...最后还有两点十分重要: 1、对于任意一个类,都需要由加载它的类加载器和这个类本身一起确立其在Java虚拟机中的唯一性,也就是一个类在JVM中的签名是加载它的类加载器和它本身,对于每一个类加载器,都拥有一个独立的类命名空间...通过自定义类加载器加载的和当前类路径相同名全类名的类只能通过反射去使用,而且即使全类名相同,由于类加载器隔离,它们其实是不相同的类。...小结 通过一些资料和实验,深化了类加载过程的一些认识。
作者:小傅哥 博客:https://bugstack.cn ❝沉淀、分享、成长,让自己和他人都能有所收获 ❞ 一、前言 截至到本章节关于字节码框架 Byte-buddy 的大部分常用 API 的使用已经通过案例介绍比较全面了...二、开发环境 JDK 1.8.0 byte-buddy 1.10.9 byte-buddy-agent 1.10.9 本章涉及源码在:itstack-demo-bytecode-2-03,可以关注「公众号...", "dataApi").define("clazzDesc", "查询数据信息").define("timeOut", 350L).build()) .make(); 这部分基本是Byte-buddy...Byte-buddy 提供的 API 方法;saveIn,把字节码信息写成 class 到执行的文件夹下。...,同时也添加了类和方法的注解信息。
什么是类加载机制? 虚拟机类加载机制:虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型。...Java语言里,类型的加载和连接过程(连接过程包括验证、准备、解析)是在程序运行期间完成的。...加载(装载)、验证、准备、初始化和卸载这五个阶段顺序是固定的,类的加载过程必须按照这种顺序开始。...有类或接口的解析,字段解析,类方法解析,接口方法解析。这里要注意如果有一个同名字段同时出现在一个类的接口和父类中,那么编译器一般都会拒绝编译。...如果父加载失败,则抛出ClassNotFoundException异常后,再调用自己的findClass()方法进行加载。 protected Class<?
初始化:初始化一个类,先初始化它的父类。虚拟机会保证一个类的初始化在多线程环境中被正确加锁和同步。 要使用类A,必须先加载类A;加载类A,就会把静态变量、静态块合并初始化,然后在调用构造器。...注意类的加载和初始化,只有一次。...byte[] b, int off ,int len),可以把字节数组的内容转换成JAVA类,并会返回Class实例。...其实就是在安全,和灵活方面进行取舍! 写一个自定义类加载器 MyClassLoader: ? 自定义类加载器 重写findClass: ? findClass Test: ?...另外,被2个不同的类加载加载的同一个类,JVM不会认为是一个类。 好了,关于JVM运行和类加载的过程就写到这里,^_^ 2017.10.29 zhangfengzhe
1.类加载器 1.1类加载器【理解】 作用 负责将.class文件(存储的物理文件)加载在到内存中 1.2类加载的过程【理解】 类加载时机 创建类的实例(对象) 调用类的类方法...解析 将类的二进制数据流中的符号引用替换为直接引用 (本类中如果用到了其他类,此时就需要找到对应的类) 初始化 根据程序员通过程序制定的主观计划去初始化类变量和其他资源 (静态变量赋值以及初始化其他资源...); } } 1.4双亲委派模型【理解】 介绍 如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行,如果父类加载器还存在其父类加载器,则进一步向上委托...,依次递归,请求最终将到达顶层的启动类加载器,如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式 1.5ClassLoader...都能够知道这个类的所有属性和方法; 对于任意一个对象,都能够调用它的任意属性和方法; 这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。
领取专属 10元无门槛券
手把手带您无忧上云