1.ClassLoader(类加载器)

1.加载:查找并加载类的二进制数据

2.连接

—验证:确保被加载的类的正确性(防止不是通过java命令生成的class文件被加载)

—准备:为类的静态变量分配内存,并将其初始化为默认值(如int默认值为0)

—解析:把类中的符号引用转换为直接引用

3.初始化:为类的静态变量赋予正确的初始值(即代码中指定的值 例:public static int a = 2)

  • JAVA程序对类的使用方式可以分为两种

  —主动使用(六种)

  —被动使用(除了主动使用的六种方法,其余的都属于被动使用)

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

  —创建类的实例

  —访问某个类或接口的静态变量,或者对静态变量赋值(int b = Test.a)

  —调用类的静态方法

  —反射,Class.forName("Test");

  —初始化了一个类的子类

  —Java虚拟机启动的时被表明为启动的类  进入cmd使用Java命令   com.xyw.Test(包含main方法)

类的加载:

  类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构

加载.class的方式

—从本地系统中直接加载

—通过网络下载.class文件

—从zip,jar等归档文件中加载.class文件

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

—将Java源文件动态编译为.class文件

类的加载的最终产品是位于堆区中的Class对象

Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口(即反射 Reflect)

有两种类型的类加载器

—Java虚拟机自带的加载器

根类加载器(Bootstrap) C++编写,程序员无法在java代码中获得该类

扩展类加载器(Extension) java实现

系统类加载器(System) java实现

—用户自定义的类加载器

java.lang.ClassLoader的子类(自定义加载器必须extends这个抽象类)

用户可以定制类的加载方式

类的验证:

类加载器并不需要等到某个类被“首次主动使用”的时再加载它

JVM规范允许类加载器在预料的某个类将要被使用的时候加载它,如果在预先加载的过程中遇到了.class文件缺失或存在错误,类加载器必须在程序首次主动使用该类的时才报告错误(LinkageError错误)

如果这个类一直没有被程序主动使用,那么类加载器就不会报告错误

类被加载后,就进入连接阶段,连接就是将已经读入内存的类的二进制数据合并到虚拟机的运行时环境中去

类的验证的内容:

1.类文件的结构检查 :确保类文件遵从java类文件的格式

2.语义检查 :确保类本身符合java语言的语法规定,比如验证final类型的类没有子类,已经final方法没有被覆盖

3.字节码验证:确保字节码流可以被JVM安全的执行,字节码代表java方法(包括静态方法和实例方法)

4.二进制兼容性的验证:确保相互引用的类之间的协调一致

类的准备:

在准备阶段,java虚拟机为类的静态变量分配内存,并设置默认的初始值,例如将为int类型的静态变量分配4个字节的内存空间,初始值为0,为long类型的静态变量分配8个字节的内存空间,默认值为0

在解析阶段,java虚拟机会把类的二进制数据中的符号引用替换为直接引用,在一个类中的方法调用另一个类的方法叫做符号引用,解析阶段,Java虚拟机会把这个符号引用替换为一个指针,指向该类的方法区内的内存位置,这个就是直接引用

在初始化阶段,Java虚拟机执行类的初始化语句,为类的静态变量赋予初始值,在程序中,静态变量初始化有两种途径1.在静态变量的声明处进行初始化2.在静态代码块中进行初始化

静态变量的声明语句,以及静态太马克都被看做类的初始化语句,Java虚拟机会按照初始化语句在类文件中的先后顺序来依次执行

类的初始化步骤:

1.假如这个类还没有被加载和连接,那就先进行加载和连接

2.假如类存在直接的弗雷,并且这个父类还没有被初始化,那就先初始化直接的父类

3.假如类中存在初始化语句,那就依次执行这些初始化语句

当java虚拟机初始化一个类时,要求它所有的父类都已经初始化,但是这条规则并不使用于接口

1.在初始化一个类时,并不会先初始化它所实现的接口

2,在初始化一个接口时,并不会先初始化它的父接口

因此,一个父接口并不会因为它的子接口或者实现类的初始化而初始化,只有当程序首次使用特定接口的静态变量时,才会导致该接口的初始化

程序中对子类的“主动使用”会导致父类的初始化,但对父类的“主动使用”并不会导致子类的初始化

只有当程序访问的静态变量或静态方法确实在当前类或当前接口中定义时,才可以认为是对类或接口的主动使用(如果只访问一个类的父类的静态变量,这样只初始化了父类,当前类没有被“主动使用”)

类的初始化时机

调用ClassLoader类的loadClass方法加载一个类,并不是对类的主动使用,不会导致类的初始化

类加载器:

类加载器用来把类加载到Java虚拟机中,从jdk1.2开始,类的加载过程采用父亲委托机制,这种机制更好的保证java平台的安全,在此委托机制中,除了java虚拟机自带的跟加载器以外,其余的类加载器都有且只有一个父类加载器,当java程序请求加载loader1加载一个类的时候,loader1首先委托自己的父加载器去加载该类,如果父加载器能够加载,则由父加载器加载,否则才由loader1加载器加载,都不能加载则抛出异常

根加载器:没有父加载器,负责加载虚拟机的核心类库,根类加载器实现依赖于低层次操作系统,属于虚拟机的实现的一部分,并没有继承ClassLoader类

扩展类加载器:它的父加载器为根类加载器(父加载器不代表父类)

系统类加载器:它的父加载器为扩展类加载器,它从环境变量classpath或者系统属性java.class.path所指定的目录中加载类,它是用户自定义的类加载器的默认父加载器

父子加载器并非继承关系,也就是说子加载器不一定要继承父加载器,是包装关系

除了以上虚拟机自带的加载器以外,用户还可以定制自己的类加载器(user-defined Class Loader).java提供了抽象类java.lang.ClassLoader,用户自定义的类加载器应该继承ClassLoader类

在父亲委托机制当中,各个加载器按照父子关系形成了树形结构,除了跟类加载器以外,其余的加载器都有且只有一个父加载器

若有一个类加载器能成功加载一个类,那么这个类加载器被称为定义类加载器,所有能成功返回Class对象的引用的类加载器(包括定义类加载器)都被称为初始类加载器

当生成一个自定义的类加载器的实例时,如果没有指定它的父加载器,那么系统类加载器就好自动成为该类的父加载器

运行时包

由同一个加载器加载的属于相同的类组成了运行时包,决定两个类是不是属于同一个运行时包,不仅要看它们的包名是否相同,还要看定义类加载器是否相同,只有属于同一运行时包的类才能相互访问包可见的类和类成员。这样的限制避免用户自定义的类冒充核心类库的方法,去访问核心类的包可见成员。假设用户自己定义一个类java.lang.Spy,并由用户自定义的类加载器加载,由于和核心类库java.lang.*由不同的加载器加载,他们不属于运行时包

要创建用户自己的类加载器,只需扩展java.lang.ClassLoader类,然后覆盖它的findClass(String name)方法即可,该方法根据参数指定的类的名字,返回对应的Class对象的引用

同一个命名空间内的类是相互可见的

子加载器的命名空间包含所有父加载器的命名空间,因此由子加载器加载的类能看见父加载器加载的类,例如系统类加载器加载的类能看见根类加载器加载的类

由父加载器加载的类不能看见子加载器加载的类

如果两个加载器之间没有直接或间接的父子关系,那么他们各自加载的类相互不可见

最新文章

  1. 关于StringBuffer和StringBuilder
  2. 实现移动设备远程登录linux服务器
  3. RGB to HSI, HSI to RGB Conversion Calculator
  4. C读取文件
  5. Java基础 Day14 泛型
  6. Less注释语法
  7. CemtOS7更改yum网易 阿里云的yum源。
  8. 汽车行业解决方案_K2助力车企实现费控/生产“端到端流程”
  9. ArrayList 加强版的数组
  10. Java与openssl的RSA算法
  11. 关于ASP.NET预编译(转自dudu)
  12. JS closure
  13. 「PKUSC2018」星际穿越(倍增)
  14. MySQL各类日志文件相关变量介绍
  15. Docker Hub Mirror
  16. mysql链接 显示 error: 'Access denied for user 'root'@'localhost' (using password: NO)'
  17. 面向对象先修:Java入门
  18. nginx 部署前期一定要关闭selinux
  19. 微信小程序 功能函数 定时震动
  20. 在进行分布式框架搭建的过程中,出现问题advised by org.springframework.transaction.interceptor.TransactionInterceptor.invoke(org.aopalliance.intercept.MethodInvocation)?

热门文章

  1. validate插件深入学习-03validate()方法配置项
  2. JAVA 重复提交
  3. Scrum Meeting 13-20151221
  4. iOS开发 QQ粘性动画效果
  5. contiki-process_run()
  6. 面试中常用的__proto__,prototype和原型链,你都了解了吗?
  7. VC界面最前端显示
  8. c#数据绑定(2)——删除DataTable的数据
  9. sql语句查询服务器的数据库,数据库的全部表和表的全部列
  10. 我的毕业设计——基于安卓和.NET的笔记本电脑远程控制系统