zoukankan      html  css  js  c++  java
  • Java类加载

    类的生命周期是:

    在一个类编译完成之后,下一步就需要开始使用类,如果要使用一个类,肯定离不开JVM。在程序执行中JVM通过装载,链接,初始化这3个步骤完成。

    类的装载是通过类加载器完成的,加载器将.class文件的二进制文件装入JVM的方法区,并且在堆区创建描述这个类的java.lang.Class对象。用来封装数据。 但是同一个类只会被类装载器装载以前

    链接就是把二进制数据组装为可以运行的状态。

    链接分为校验,准备,解析这3个阶段

    校验一般用来确认此二进制文件是否适合当前的JVM(版本),

    准备就是为静态成员分配内存空间,。并设置默认值

    解析指的是转换常量池中的代码作为直接引用的过程,直到所有的符号引用都可以被运行程序使用(建立完整的对应关系)

    完成之后,类型也就完成了初始化,初始化之后类的对象就可以正常使用了,直到一个对象不再使用之后,将被垃圾回收。释放空间。

    当没有任何引用指向Class对象时就会被卸载,结束类的生命周期

    ==============================================================================

    类加载概念:

    类加载器(class loader)用来加载 Java 类到 Java 虚拟机中。一般来说,Java 虚拟机使用 Java 类的方式如下:Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类加载器负责读取 Java 字节代码,并转换成java.lang.Class类的一个实例。每个这样的实例用来表示一个 Java 类。通过此实例的 newInstance()方法就可以创建出该类的一个对象。

    lip:

    系统提供的加载器有根加载器(C++编写),扩展类加载器,系统加载器三类加载器。

    Java类的加载过程采用全盘负责委托机制:

    全盘负责:例如类A依赖类B,类加载器加载了类A那么类B也会交由该加载器去加载。

    委托机制:类加载器去加载某个类,先是交由该类加载器的父加载器去加载,如果父加载器的还有父级,则继续交由父级去加载。父级加载器加载到了,则直接返回。如果父加载器没有加载到,则有该类加载器去加载,如果加载到了则返回,没有则抛出ClassNotFoundException异常【委托机制的作用是保证类加载的安全性,防止自定义的类和系统类冲突,例如自定义一个java.lang.String类,系统加载还会是JDK自带的那个】

     hy:

    java加载类,是动态加载的。当需加载一个类的时候,把字节码读入内存转换为对象,然后初始化出一个对象。

    类加载遵循3个原则:单一性,可见性(一个加载器只能加载一次),以及委托机制(交由父类加载)

    可见性:

     1 @Test
     2     public void testClass()
     3     {
     4         try {          
     5             //printing ClassLoader of this class
     6             System.out.println("ClassLoaderTest.getClass().getClassLoader() : "
     7                                  + Test1.class.getClassLoader());
     8 
     9             //trying to explicitly load this class again using Extension class loader
    10             Class.forName("test.ClassLoaderTest", true
    11                             ,  Test1.class.getClassLoader().getParent());
    12         } catch (ClassNotFoundException ex) {
    13             System.out.println("ClassLoaderTest.getClass().getClassLoader() : "
    14                 + ex);
    15         }
    16     }
    ClassLoaderTest.getClass().getClassLoader() : sun.misc.Launcher$AppClassLoader@19821f
    ClassLoaderTest.getClass().getClassLoader() : java.lang.ClassNotFoundException: test.ClassLoaderTest

    提问:一个类是否能被两个不同类加载器加载?

    系统加载器会抛出 java.lang.ClassCastException异常,所以可以使用自定义加载类。但需要自己实现。

    引用::比如一个 Java 类 com.example.Sample,编译之后生成了字节代码文件 Sample.class。两个不同的类加载器ClassLoaderA和 ClassLoaderB分别读取了这个 Sample.class文件,并定义出两个 java.lang.Class类的实例来表示这个类。这两个实例是不相同的。对于 Java 虚拟机来说,它们是不同的类。试图对这两个类的对象进行相互赋值,会抛出运行时异常ClassCastException

    参考资料:

    http://www.importnew.com/6581.html

    http://wiki.jikexueyuan.com/project/java-reflection/java-reload.html

    https://www.ibm.com/developerworks/cn/java/j-lo-classloader/

  • 相关阅读:
    TinyMail研究—Camellite的插件系统
    Dual Tone Multifrequency
    Linux PPP 数据收发流程
    这个五一怎么过?
    Linux下的磁盘加密方法
    udev的实现原理
    c语言中程序的循环控制,for语句。
    创建一个函数,将和有n个元素的数组中的key相等的所有元素的下标存储在另一数组中,并返回和key元素相同的元素的个数。
    c语言中数组元素的哨兵查找法
    c语言中数组,一般数组
  • 原文地址:https://www.cnblogs.com/wanghongye/p/5129602.html
Copyright © 2011-2022 走看看