• 探索JVM底层奥秘ClassLoader源码分析


    1JVM基本结构:

    *.java--------javac编译------>*.class-----ClassLoad加载---->运行时数据区------->执行引擎,接口库------>本地方法库

    2、JVM运行流程:

     

    public class Dome {

    private static int tem=1;

    static {

    tem=2;

    System.out.println(tem);

    }

    public static void main(String[] args) {

    tem=6;

    System.out.println(tem);

    }

    }

    类的装载:

    加载,连接(验证,准备,解析),初始化,使用,卸载

    Class会保存类的定义或者结构到堆中

    初始化:执行类的构造器《clinit》,为类的静态变量赋予正确的初始值

    构造器:

    1、static变量

    2、Static{}语句块

    构造方法:实列化对象

    3、类加载器双亲委派模型

    Bootstrat ClassLoader :启动类加载器(C++,内核)【rt.jar】  null

    Extension ClassLoader:扩展类加载器---extends->%JAVA_HOME%/lib/ext/*.jarClassLoader

    App ClassLoader:系统类加载器 ----extends-->Classpath下加载】ClassLoader扩展类加载器)

    自定义类加载器: extends ClassLoader系统类加载器 ---【自定义加载】

    public static void main(String[] args) {

    //System.out.println(Dome2.class.getClassLoader());

    ClassLoader classLoader=Dome2.class.getClassLoader();

    while(classLoader!=null) {

    System.out.println(classLoader);

    classLoader=classLoader.getParent();

    }

    System.out.println(classLoader);

    }

    编译:

    sun.misc.Launcher$AppClassLoader@2a139a55   》系统类加载器

    sun.misc.Launcher$ExtClassLoader@7852e922   》扩展类型加载器

    Null  》启动类加载器

    jdkrt.jar下找到java.lang.classLoader类,找到类加载方法:

    @paremname,类的二进制字节流

      public Class<?> loadClass(String name) throws ClassNotFoundException{

            return loadClass(name, false);

       }

    查找是否有这个类:

    有:从父类中加载

    无:从BootstrapClass加载

    //parent:

      // The parent class loader for delegation

        // Note: VM hardcoded the offset of this field, thus all new fields

    // must be added *after* it

    private final ClassLoader parent;//父类委派机制 :包含关系

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

            throws ClassNotFoundException

        {

            synchronized (getClassLoadingLock(name)) {

                // First, check if the class has already been loaded

                Class<?> c = findLoadedClass(name);

                if (c == null) {

                    long t0 = System.nanoTime();

                    try {

                        if (parent != null) {                       

     c = parent.loadClass(name, false);

                        } else {

                            c = findBootstrapClassOrNull(name);

                        }

                    } catch (ClassNotFoundException e) {

                        // ClassNotFoundException thrown if class not found

                        // from the non-null parent class loader

                    }

                    if (c == null) {

                        // If still not found, then invoke findClass in order

                        // to find the class.

                        long t1 = System.nanoTime();

                        c = findClass(name); //自定义类加载【回调方法】

                        // this is the defining class loader; record the stats

                        sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);

                        sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);

                        sun.misc.PerfCounter.getFindClasses().increment();

                    }

                }

                if (resolve) {

                    resolveClass(c);

                }

                return c;

            }

        }

    被子类重写:

     protected Class<?> findClass(String name) throws ClassNotFoundException {

            throw new ClassNotFoundException(name);

    }

    实列:自定义类加载器

    一个本地的Demo.class文件,一个编译环境中的Demo.class文件

    测试调用类:

    public class Dome {

    public Dome() {

    System.out.println("A Dome"+Dome.class.getClassLoader());

    }

    }

    需求实现类:

    package com.cn.classload;

    import java.io.ByteArrayOutputStream;

    import java.io.File;

    import java.io.FileInputStream;

    import java.io.IOException;

    import java.io.InputStream;

    /**

     * @Description: 自定义类加载器

     * @ClassName: MyClassLoader

     * @author

     * @date 2019915

     *

     */

    public class MyClassLoader extends ClassLoader {

    private String path;// 加载类的路劲

    private String name;// 类加载器名称

    public MyClassLoader(String name, String path) {

    super();// 让系统类加载器成为该类的父类

    this.name = name;

    this.path = path;

    }

    // 父类委托机制:父类加载器

    public MyClassLoader(ClassLoader parent, String name, String path) {

    super(parent);

    this.name = name;

    this.path = path;

    }

    /**

     * 加载自定义的ClassLoader Title: findClass Description:

     *

     * @param name:包路径

     * @return

     * @throws ClassNotFoundException

     * @see java.lang.ClassLoader#findClass(java.lang.String)

     *

     */

    @Override

    protected Class<?> findClass(String name) throws ClassNotFoundException {

    byte[] data = readClassFileToByteArray(name);

    return this.defineClass(name, data, 0, data.length);

    }

    /**

     * Title: toString Description:

     *

     * @return

     * @see java.lang.Object#toString()

     *

     */

    @Override

    public String toString() {

    // TODO Auto-generated method stub

    return this.name;

    }

    /**

     * @Description: 获取.class文件的字节数组

     * @Title: readClassFileToByteArray

     * @date 2019-09-15 17:27

     * @param @param name2

     * @param @return 参数

     * @return byte [] 返回类型

     * @throws @return byte []

     * @param name2

     * @return

     */

    private byte[] readClassFileToByteArray(String name) {

    InputStream iStream = null;

    byte[] returnData = null;

    name = name.replaceAll("\.", "/");

    String filePath = this.path + name + ".class";

    System.out.println("路径:"+filePath);

    File file = new File(filePath);

    ByteArrayOutputStream os = new ByteArrayOutputStream();

    try {

    iStream = new FileInputStream(file);

    int tmp = 0;

    while ((tmp = iStream.read()) != -1) {

    os.write(tmp);

    }

    returnData = os.toByteArray();

    } catch (Exception e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    } finally {

    if (os != null) {

    try {

    os.close();

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

    if (iStream != null) {

    try {

    iStream.close();

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

    }

    return returnData;

    }

    }

    测试类:

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {

    MyClassLoader zhangfeimyClassLoader=new MyClassLoader("zhangfei","D:/com/cn/classload/");

    //MyClassLoader wukongmyClassLoader=new MyClassLoader(zhangfeimyClassLoader,"wukong","D:/com/cn/classload/");//现在张飞是悟空的父类委派加载器输出的就是编译环境中的Dome.class文件

    MyClassLoader wukongmyClassLoader=new MyClassLoader(null,"wukong","D:/com/cn/classload/");//这里父类没有就是用自定义的加载器输出的就是本地磁盘上的Dome.class文件

    Class<?> c=wukongmyClassLoader.loadClass("Dome");

    c.newInstance();

    }

    学着把生活的苦酒当成饮料一样慢慢品尝, 不论生命经过多少委屈和艰辛, 我们总是以一个朝气蓬勃的面孔, 醒来在每一个早上。
  • 相关阅读:
    O'Reilly总裁提姆奥莱理:什么是Web 2.0
    在MFC程序中显示JPG/GIF图像
    VC窗体设计集锦
    VxWorks使用说明书
    关于双缓冲绘图之二
    如何将EVC4工程升级到VS.NET2005工程
    某个正在运行的程序的CPU占用率
    如何去掉回车键和取消键
    探索NTFS
    ARM上的C编程
  • 原文地址:https://www.cnblogs.com/yhm9/p/11525564.html
Copyright © 2020-2023  润新知