类加载器,自定义类加载器

参考:
一篇文章读懂Java类加载器
全面解析Java类加载器

类加载器

  • 类加载器结构:

    类加载器,自定义类加载器_第1张图片

  • ClassLoader类是一个抽象类,但却没有包含任何抽象方法。

  • 如果要实现自己的类加载器且不破坏双亲委派模型,只需要继承ClassLoader类并重写findClass方法。

  • 如果要实现自己的类加载器且破坏双亲委派模型,则需要继承ClassLoader类并重写loadClass,findClass方法。

自定义类加载器

  • 实现自定义类加载器的三步:

1.继承ClassLoader
2.重写findClass()方法
3.调用defineClass()方法

一个基本的自定义类加载器代码如下:

/*
 * John Han.
 * Copyright (c) 2019-2019 All Rights Reserved.
 */
package com.john.learn.basic.class_loader;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

/*
 * 自定义类加载器
 * author: john.
 * version: CustomClassLoader.java, v 0.1 2019年05月18日 下午5:14 Exp.
 */
public class CustomClassLoader extends ClassLoader {

  @Override
  protected Class findClass(String name) throws ClassNotFoundException {
    try {
      byte[] result = getClassFromCustomPath(name);
      if (result == null) {
        throw new FileNotFoundException(name);
      } else {
        // defineClass方法将字节码转化为类
        return defineClass(name, result, 0, result.length);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    throw new ClassNotFoundException(name);
  }

  private byte[] getClassFromCustomPath(String name) {
    // 从自定义路径中加载指定类,返回类的字节码文件
    InputStream in = null;
    ByteArrayOutputStream out = null;
    String path = "/Users/john/" + name + ".class";
    try {
      in = new FileInputStream(path);
      out = new ByteArrayOutputStream();
      byte[] buffer = new byte[2048];
      int len = 0;
      while ((len = in.read(buffer)) != -1) {
        out.write(buffer, 0, len);
      }
      return out.toByteArray();
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        in.close();
        out.close();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    return null;
  }

  public static void main(String[] args) {
    CustomClassLoader customClassLoader = new CustomClassLoader();
    try {
      Class clazz = Class.forName("One", true, customClassLoader);
      Object obj = clazz.newInstance();
      // cn.xpleaf.coding.c4.CustomClassLoader@610455d6
      System.out.println(obj.getClass().getClassLoader());
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

你可能感兴趣的:(类加载器,自定义类加载器)