类在执行之前会执行三个步骤:加载 ->   连接  -> 初始化

1.java中类的加载

java 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个Class对象,用来封装类在方法区的数据结构。可以把堆区的Class理解为方法区的一面镜子,对应方法区的类的数据结构,通过这面镜子实现类的调用。

加载.class文件的多种方式:

1.从本地系统中直接加载

2.通过网络下载.class文件

3.从zip,jar里加载.class文件

4.从专有的数据库中提取.class文件

5.将java源文件动态编译为.class文件

 类加载的最终结果是生成位于堆中的Class对象,Class对象封装了类在方法区内的数据结构,并且向java程序员提供了访问方法区内的数据结构的接口

查看源码得到Class对象只能由java虚拟机来创建,其构造函数私有化

2.连接

1. 验证:确保被加载的类的正确性(主要防止恶心的class文件被加载)

2. 准备:为类的静态变量分配内存,并将其初始化为默认值

3. 解析:把类中的符合引用转换为直接引用

3.初始化

    为类的静态变量赋予正确的初始值

所有的java虚拟机实现必须在每一个类或接口被java程序“首次主动使用”时才初始化

java对类的使用方式分为:主动使用,被动使用

主动使用有六种:(除这6种外,其他都是被动使用)

1。创建类的实例

2。访问某个类或接口的静态变量或对该静态变量赋值

3。调用类的静态方法

4。反射

5。初始化类的子类

6。java虚拟机启动时被标注位启动类的类

4.类加载器Classloader

类加载器类型

1.java虚拟机自带的类加载器:

-----根类加载器Bootstrap

该类加载器没有父类加载器,它负责加载虚拟机的核心类库,如java.lang.String等,根类加载器用于在启动JVM时加载类,以使JVM能正常工作,因而它是用Native(c++)代码实现的,最早被创建出来,处于最底层。它并没有继承java.lang.ClassLoader类。

-----扩展类加载器Extension

该类加载器的父类加载器是根类加载器。它从java.ext.dirs系统属性所指定的目录获取加载类库或从JDK的安装目录的jre\lib\ext子目录下加载类库。如果把jar放到这个目录下,也会自动用扩展类加载器加载。扩展类加载器是java类,是java.lang.ClassLoader类的子类

-----系统类加载器System

也成为应用类加载器,它的父类加载器是扩展类加载器,它将加载CLASSPATH中配置的目录和jar文件,它是用户自定义类加载器的默认父类加载器,系统类加载器是java类,是java.lang.ClassLoader类的子类

2.用户自定义类加载器:是java.lang.ClassLoader的子类,可以定义类加载器

类加载器机制

类加载器用来把类加载到java虚拟机中,类加载过程采用的是父亲委托机制,这种机制能很好的保证java平台的安全,因为在这种机制下用户定义的类加载器不可能加载应由父加载器加载的可靠类,如java.lang.String总是由根类加载器加载。在此委托机制中,除了java的根类加载器以外,其余的加载器都有且只有一个父加载器。

自定义类加载器

用户自定义类加载器需要满足父委托机制,默认系统类加载器为其父加载器。要实现自定义加载器,只需要集成ClassLoader类,然后覆盖findClass(String name)方法,该方法根据参数指定加载类的名字,返回对应的Class对象的引用

自定义类加载器类: MyClassLoader

  1. package com.longpo.classloader;

  2. import java.io.File;

  3. import java.io.FileInputStream;

  4. import java.io.FileNotFoundException;

  5. import java.io.IOException;

  6. import java.io.InputStream;

  7. public class MyClassLoader extends ClassLoader {

  8. private String name; //类加载器的名字

  9. private String path="D:\\"; //加载类的路径

  10. private final String type=".class"; //class文件的扩展名

  11. public MyClassLoader(String name)

  12. {

  13. super();

  14. this.name=name;

  15. }

  16. //指定父类加载器

  17. public MyClassLoader(ClassLoader parent ,String name)

  18. {

  19. super(parent);//显示指定该加载器的父加载器

  20. this.name=name;

  21. }

  22. //设置加载class的路径

  23. public String getPath() {

  24. return path;

  25. }

  26. public void setPath(String path) {

  27. this.path = path;

  28. }

  29. @Override

  30. public String toString() {

  31. return "MyClassLoader :" + name ;

  32. }

  33. //读取对应class文件的二进制数据---这里简单读取

  34. private byte[] loadClassData(String name)

  35. {

  36. //根据要加载的类名找到对应的文件

  37. name=name.replace(".", "\\");//com.longpo.test目录结构是\\

  38. File file=new File(path+name+type);

  39. //根据文件大小来创建字节数组

  40. byte[]bytes=new byte[(int)file.length()] ;

  41. try {

  42. InputStream is = new FileInputStream(file);

  43. int len=is.read(bytes);//返回读取字节的长度

  44. is.close();

  45. } catch (FileNotFoundException e) {

  46. e.printStackTrace();

  47. } catch (IOException e) {

  48. e.printStackTrace();

  49. }

  50. return bytes;

  51. }

  52. //一定要重写该方法

  53. @Override

  54. public  Class<?> findClass(String name) throws ClassNotFoundException {

  55. //得到class文件的二进制数据

  56. byte[]data=loadClassData(name);

  57. return this.defineClass(name, data, 0,data.length);//返回class对象的引用

  58. }

  59. }

定义一个测试加载类:Simple

  1. package com.longpo.classloader;

  2. public class Simple {

  3. public Simple( )

  4. {

  5. System.out.println("Simple的类加载器的名字是:"+this.getClass().getClassLoader());

  6. }

  7. }

测试自定义加载类:Test

  1. package com.longpo.classloader;

  2. public class Test {

  3. public static void main(String[] args) throws Exception{

  4. //loader1的父加载器默认是系统加载器--上面还有系统加载器,扩展加载器,根加载器

  5. MyClassLoader loader1=new MyClassLoader("loader1");

  6. loader1.setPath("D:\\lib\\loader1\\");//loader1加载路径

  7. //loader2的父加载器为loader1--上面有loader1加载器,系统加载器,扩展加载器,根加载器

  8. MyClassLoader loader2=new MyClassLoader(loader1,"loader2");

  9. loader2.setPath("D:\\lib\\loader2\\");//loader2加载路径

  10. //loader3的父加载器为null,即根加载器--上面只有根加载器

  11. MyClassLoader loader3=new MyClassLoader(null,"loader3");

  12. loader3.setPath("D:\\lib\\loader3\\");//loader3加载路径

  13. test(loader2);

  14. test(loader3);

  15. }

  16. public static void test(ClassLoader loader)throws Exception{

  17. Class clazz=loader.loadClass("com.longpo.classloader.Simple");//loadClas会自动调用findClass方法

  18. Object object=clazz.newInstance();

  19. }

  20. }

此时把编译好的class文件发到对应加载器目录的文件夹里面,我用的是Eclipse,可在项目的目录的bin目录下找到.class文件

在Eclipse运行Test,得结果:

各个加载器的关系为

使用loader2加载Simple时,根据父亲委托机制,会从根加载器开始尝试加载,一直往下加载,之道系统类加载器加载成功。使用loader3加载Simple,根据父亲委托机制,先由根加载器加载,加载失败后有loader3自己加载

原文地址 http://techfoxbbs.com/blog-1-2.html

转载于:https://blog.51cto.com/wufanxin/1660059

java的类加载器ClassLoader相关推荐

  1. Java虚拟机学习 - 类加载器(ClassLoader)

    类加载器 类加载器(ClassLoader)用来加载 class字节码到 Java 虚拟机中.一般来说,Java 虚拟机使用 Java 类的方式如下:Java 源文件在经过 Javac之后就被转换成 ...

  2. java类加载器_类加载器ClassLoader

    上篇文章说到,Class类可以通过一个类的全限定名去加载类,那么底层是如何去加载的呢?这就是我们今天要聊的类加载器ClassLoader,其可以通过一个类的全限定名来获取描述此类的二进制字节流,也即是 ...

  3. java什么时候会触发类加载_Java 类加载器classLoader | 七日打卡

    类加载器是什么? Java程序启动时(或者在运行的过程中), jvm(Java虚拟机)会完成类的加载, 其中第一步就是使用类加载器classLoader将二进制流(.class文件)加载到内存中. 类 ...

  4. java classloader详解_Java类加载器(ClassLoader)详解

    本文主要讲述Java ClassLoader的工作原理,这为后面将Android App代码热替换或者插件化升级做铺垫 一. 类加载器 ClassLoader即常说的类加载器,其功能是用于从Class ...

  5. Java 程序执行过程的内存流程图(结合类加载器 ClassLoader 讲解)

    Student s = new Student(); s.play(); Student s2 = new Student(); 以上代码的执行流程如下: JVM 作为操作系统的一个迚程在系统中执行, ...

  6. 【Android 逆向】类加载器 ClassLoader ( 使用 DexClassLoader 动态加载字节码文件 | 拷贝 DEX 文件到内置存储 | 加载并执行 DEX 字节码文件 )

    文章目录 一.拷贝 Assets 目录下的 classes.dex 字节码文件到内置存储区 二.加载 DEX 文件并执行其中的方法 三.MainActivity 及执行结果 四.博客资源 一.拷贝 A ...

  7. 【Android 逆向】类加载器 ClassLoader ( Android 的八种类加载器 | ClassLoader | BaseDexClassLoader | DexClassLoader )

    文章目录 一.Android 类加载器 1.ClassLoader 抽象类 2.BootClassLoader 3.BaseDexClassLoader 4.PathClassLoader 5.Dex ...

  8. 【Android 逆向】类加载器 ClassLoader ( 启动类加载器 | 扩展类加载器 | 应用类加载器 | 类加载的双亲委托机制 )

    文章目录 一.类加载器 二.类加载的双亲委托机制 一.类加载器 Java 虚拟机 ClassLoader 类加载器 : Bootstrap ClassLoader : 启动类加载器 , 该 加载器由 ...

  9. java中的类加载器有,Java自定义的类加载器,java自定义加载,在java中类加载器有以...

    Java自定义的类加载器,java自定义加载,在java中类加载器有以 在java中类加载器有以下几种java虚拟机自带的加载器 1)根类加载器(Bootstrap,c++实现)2)扩展类加载器(Ex ...

最新文章

  1. Java运行时动态加载类之Class.forName
  2. php源代码compress,Php常见开源程序gzip网页压缩功能手动关闭或开启方法大全
  3. 【Vs2015】 常用字体的设置
  4. c语言编程用进退法求搜索区间代码,用c对函数进行优化的问题
  5. Windows API——FindFirstFile——查找文件
  6. 3.5W 字详解 Java 集合
  7. 《游戏编程模式》总结
  8. 什么是思考?如何主动思考?
  9. HyperLogLog浅析
  10. Java关于继承中的内存分配
  11. 30多个Java实战项目,全部在这里了。
  12. python 登入界面 代码
  13. 开发一个app多少钱?app开发费用明细、app开发成本计算
  14. 数据分析案例-电影数据分析
  15. 笔记本电脑连不上WIFI
  16. moment的使用——简单易懂
  17. 电脑调分辨率黑屏了怎么办_调显示器分辨率黑屏怎么办
  18. 蓝牙设备删除失败_十代混动雅阁车载蓝牙连接不上怎么办?
  19. 这5款堪称神器的插件,能让你的效率提升3-4倍!还不知有点遗憾
  20. php设计模式:单例模式

热门文章

  1. 宝骏530中控屏怎么安装软件_【中山永豊】宝骏530音响升级美国DD双低音,炸机效果征服全场观众!...
  2. 20191015:基数排序法
  3. sqlserver 字符串转换成日期、int与varchar类型转换及保留两位小数
  4. es的master选举摘要
  5. 嵌入式设备中支持国密算法的方法
  6. 为SSD加速 实战4KB对齐技巧2/3
  7. Mongodb系列:初识Mongodb
  8. 华为中兴腾讯拿下国家科学技术进步奖,中南大学一作奖项总数全国第三
  9. Goodfellow新研究:对抗样例让机器与人类双双上当 | 论文
  10. 视频全程:哈萨比斯首次公开解读AlphaZero