JVM学习笔记5

bilibili-深入理解JVM 虚拟机 学习笔记

JVM学习笔记 1
JVM学习笔记 2
JVM学习笔记 3
JVM学习笔记 4

P14_ClassLoader源码分析与实例剖析(14)

类加载器是负责加载类的对象。ClassLoader 类是一个抽象类。如果给定类的二进制名称,那么类加载器会试图查找生成构成类定义的数据。一般策略是将名称转换为某个文件名,然后从文件系统读取该名称的“类文件”。

每个 Class 对象都包含一个对定义它的 ClassLoader 的引用

数组类的 Class 对象不是由类加载器创建的,而是由 Java 运行时根据需要自动创建。数组类的类加载器由 Class.getClassLoader() 返回,该加载器与其元素类型的类加载器是相同的如果该元素类型是基本类型,则该数组类没有类加载器

应用程序需要实现 ClassLoader 的子类,以扩展 Java 虚拟机动态加载类的方式。

类加载器通常由安全管理器使用,用于指示安全域。

ClassLoader 类使用委托模型搜索类和资源。每个 ClassLoader 实例都有一个相关的父类加载器。需要查找类或资源时,ClassLoader 实例会在试图亲自查找类或资源之前,将搜索类或资源的任务委托给其父类加载器。虚拟机的内置类加载器(称为 “bootstrap class loader”)本身没有父类加载器,但是可以将它用作 ClassLoader 实例的父类加载器。

通常情况下,Java 虚拟机以与平台有关的方式,从本地文件系统中加载类。例如,在 UNIX 系统中,虚拟机从 CLASSPATH 环境变量定义的目录中加载类。

然而,有些类可能并非源自一个文件;它们可能源自其他来源(如网络),也可能是由应用程序构造的。defineClass 方法将一个 byte 数组转换为 Class 类的实例。这种新定义的类的实例可以使用 Class.newInstance 来创建。

类加载器所创建对象的方法和构造方法可以引用其他类。为了确定引用的类,Java 虚拟机将调用最初创建该类的类加载器的 loadClass 方法。

– ClassLoader JavaDoc

package new_package.jvm.p14;

public class MyTest15 {

    public static void main(String[] args) {

        String[] strings = new String[2];
        System.out.println(strings.getClass().getClassLoader());

        MyTest15[] myTest15s = new MyTest15[2];
        System.out.println(myTest15s.getClass().getClassLoader());

        int[] ints = new int[2];
        System.out.println(ints.getClass().getClassLoader());
    }
}

// null
// sun.misc.Launcher$AppClassLoader@18b4aac2
// null

P15_自定义类加载器深入详解(15)

网络类加载器子类必须定义方法 findClass 和 loadClassData,以实现从网络加载类。下载组成该类的字节后,它应该使用方法 defineClass 来创建类实例。示例实现如下:

     class NetworkClassLoader extends ClassLoader {
         String host;
         int port;

         public Class findClass(String name) {
             byte[] b = loadClassData(name);
             return defineClass(name, b, 0, b.length);
         }

         private byte[] loadClassData(String name) {
             // load the class data from the connection
              . . .
         }
     }

package new_package.jvm.p15;

import java.io.*;

public class MyClassLoader extends ClassLoader {

    public static final String fileExtension = ".class";

    public MyClassLoader() {
        super();
    }

    private byte[] loadClassData(String name) {

        byte[] data = null;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {

            inputStream = new FileInputStream(new File(name));
            outputStream = new ByteArrayOutputStream();
            int ch;
            while (-1 != (ch = inputStream.read())) {
                outputStream.write(ch);
            }
            data = ((ByteArrayOutputStream) outputStream).toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                inputStream.close();
                outputStream.close();
            } catch (Exception e2) {
                e2.printStackTrace();

            }
        }
        return data;
    }

    @Override
    protected Class<?> findClass(String name) {
        String fileName = name + fileExtension;
        byte[] bytes = loadClassData(fileName);
        return defineClass(fileName, bytes, 0, bytes.length);
    }

}

---

package new_package.jvm.p15;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class MyClassLoaderTest {

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        ClassLoader classLoader = new MyClassLoader();
        Class clazz = classLoader.loadClass("MD5Util");

        String str = "Hello World";
        System.out.println(MD5UtilCopy.MD5Encode(str));

        Object obj = clazz.newInstance();
        Method method = clazz.getMethod("MD5Encode", new Class[]{String.class});
        Object result = method.invoke(obj, new Object[]{str});
        System.out.println(result);

    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值