【Java】类加载

来源:互联网 发布:nba新秀菜鸟赛季数据 编辑:程序博客网 时间:2024/06/05 11:40
1.研究Java类加载目的

便于我们使用自定义类加载器;对于理解编译原理也有很大帮助。

2.研究Java类载作用

2.1 加密。java代码很容易被反编译,如果你需要把自己的代码进行加密,可以先将编译后的代码用某种加密算法加密,然后实现自己的类加载器,负责将这段加密后的代码还原,以被操作系统所识别。这样,别人看到的是加密后的.class文件,无法进行反编译。

2.2从指定来源加载。如果字节码文件不是采用标准的方式来加载代码,可能从数据库或者网络上加载,就需要自定义类加载器,从指定路径加载类文件。也为android的插件技术和热更新提供了支持。

2.3性能。基于实际情况,动态创建代码并执行。

3.概述

Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数,属性和方法等,Java允许用户借由这个Class相关的元信息对象间接调用Class对象的功能。虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验,转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。

4.具体工作机制

Java源文件*.java-->java编译器-->字节码文件(*.class)-->类装载器-->字节码校验器-->解释器-->操作系统,整个文件被load到内存区,一系列动作之后,最终形成了操作系统可以识别的代码,操作系统找到程序入口main方法开始执行。其中,heap(new出来的东西放在里面)、stack(局部变量)、data segment(静态变量或字符串常量)、code segment(存放代码)。

JVM将Main.class加载到内存如下:首先,寻找JRE目录,找到jvm.dll,并初始化JVM;然后产生一个Bootstrap Loader(启动类加载器),Bootstrap Loader自动加载Extended Loader(标准扩展类加载器),并将其父loader设置为Bootstrap loader;Bootstrap Loader自动加载Appclass loader(系统类加载器),并将其父loader设为Extended Loader。最后由Appclass loader加载Main类。

加载过程包括: 加载(loading)----验证(Vertification)----准备(Preparation)----解析(Resolution)-----初始化(Initialization)----使用(using)-----卸载(unloading)

加载:查找和导入Class文件;可以使用系统的加载器,也可以是自定义的加载器;比如从jar war 读取class文件,当然android中通过自定义加载器还可以读取dex中文件。

校验:检查载入Class文件数据的正确性;包括文件格式验证,元数据验证,字节码验证,符号引用验证

准备:给类的静态变量分配存储空间;

解析:将符号引用转成直接引用;包括类或接口的解析,字段解析,类方法解析,接口方法的解析,

初始化:对类的静态变量,静态代码块执行初始化操作

5.类加载器

(1) Bootstrap ClassLoader : 将存放于JRE\lib目录中的,或者被-Xbootclasspath参数所指定的路径中的,并且是虚拟机识别的(仅按照文件名识别,如 rt.jar 名字不符合的类库即使放在lib目录中也不会被加载)类库加载到虚拟机内存中。启动类加载器无法被Java程序直接引用

(2) Extension ClassLoader : 将JRE\lib\ext目录下的,或者被java.ext.dirs系统变量所指定的路径中的所有类库加载。开发者可以直接使用扩展类加载器。

(3) Application ClassLoader : 负责加载用户类路径(ClassPath)上所指定的类库,开发者可直接使用。

java.lang.ClassLoader中几个最重要的方法:

 //加载指定名称(包括包名)的二进制类型,供用户调用的接口

public Class<?> loadClass(String name);

//加载指定名称(包括包名)的二进制类型,同时指定是否解析(但是,这里的resolve参数不一定真正能达到解析的效果),供继承用

protected synchronized Class<?> loadClass(String name, boolean resolve);

protected Class<?> findClass(String name)

//定义类型,一般在findClass方法中读取到对应字节码后调用,可以看出不可继承(说明:JVM已经实现了对应的具体功能,解析对应的字节码,产生对应的内部数据结构放置到方法区,所以无需覆写,直接调用就可以了)

protected final Class<?> defineClass(String name, byte[] b, int off, int len) throws ClassFormatError{}

6.双亲委派模型

如果一个类加载器收到类加载的请求,他首先不会自己去加载这个类, 而是把这个请求委派给父类去执行,父类返回信息说自己不能完成请求,才会由自己来执行,好处就是比如Object类是基类,很多类都是继承他 所以得先加载这个类。破坏这个模型:代码热替换,热部署的出现,OSGI环境下不再是树状结构,发展成为了网状的结构,

7.反射

Reflection机制允许程序在正在执行的过程中,利用Reflection APIs取得任何已知名称的类的内部信息,包括:package、 type parameters、 superclass、 implemented interfaces、 inner classes、 outer classes、 fields、 constructors、 methods、 modifiers等,并可以在执行的过程中,动态生成instances、变更fields内容或唤起methods。


参考资料:《深入理解java虚拟机》

知行办公,专业移动办公平台 https://zx.naton.cn/

原创团队
【总监】十二春秋之,3483099@qq.com;
【Master】zelo,616701261@qq.com;【运营】运维艄公,897221533@qq.com;
【产品设计】流浪猫,364994559@qq.com;【体验设计】兜兜,2435632247@qq.com;
【iOS】淘码小工,492395860@qq.com;iMcG33K,imcg33k@gmail.com;
【Android】人猿居士,1059604515@qq.com;思路的顿悟,1217022114@qq.com;
【java】首席工程师MR_W,feixue300@qq.com;【测试】土镜问道,847071279@qq.com
【数据】fox009521,42151960@qq.com;【安全】保密,你懂的。

原创粉丝点击