【JVM学习笔记】---类加载器Classloader源码分析

  1. 类加载器是负责加载类的对象。 ClassLoader是一个抽象类。 给定一个类的***binary name *** ,类加载器应该尝试***定位或生成***构成类的定义的数据。 典型的策略是将名称转换为文件名,然后从文件系统中读取该名称的“类文件”。
    PS:
    (1)什么是Binary names?
    任何类名以字符串参数的形式提供给ClassLoader的方法,其中字符串参数必须是The Java™ Language Specification的如上定义的二进制名称,有效的类名的示例包括:
    “java.lang.String”
    “javax.swing.JSpinner D e f a u l t E d i t o r " " j a v a . s e c u r i t y . K e y S t o r e DefaultEditor" "java.security.KeyStore DefaultEditor""java.security.KeyStoreBuilder$FileBuilder$1”(1代表FileBuilder的第一个匿名内部类)
    “java.net.URLClassLoader$3$1”
    (2)定位与生成的含义:
    定位:数据已经真真切切存在于某个地方,进而找到该地方,例如我们自己所编写的类,或者使用JDK源码包里的类,如Java.lang.string。
    生成:运行期动态生成的一些类,运行期之前不存在,如动态代理。

    2. 每个Class对象包含一个获得加载该类的加载器所对应的方法:public ClassLoader getClassLoader​()
    3. 数组类所对应Class对象不是由类加载器创建的,而是根据Java运行时的要求自动创建。除此之外,其他类的Class对象一定是由类加载器创建的。 Class.getClassLoader()返回的数组类的类加载器与其元素类型的类加载器相同; 如果元素类型是原始类型,则数组类没有类加载器。
    代码:public class MyTest15{
    public static void main(String[] args){
    String[] strings=new String[2];
    System.out.println(strings.getClass());
    System.out.println(strings.getClass().getClassLoader());//输出为null,因为String类型是由根加载器加载的。
    MyTest15[] mytest15=new MyTest15[2];
    System.out.println(mytest15.getClass().getClassLoader()); //输出应用类加载器
    int[] arr=new int[2];
    System.out.println(arr.getClass().getClassLoader()); //输出null,此null非彼null
    }
    }

    4.创建的目的是为了扩展Java虚拟机动态加载类的方式(JVM默认的动态加载类的方式是双亲委托机制)。
    5. 安全管理员通常可以使用类加载器来指示安全域。
    6. Java虚拟机以平台相关的方式从本地文件系统加载类。 然而,一些类可能不是源于文件; 它们可以来自诸如网络的其他来源,或者它们可以由应用构建。 方法defineClass将字节数组转换为类别Class的实例。 这个新定义的类的实例可以使用Class.newInstance创建。
    7. 类加载器创建的对象的方法和构造函数可以引用其他类。 要确定所引用的类,Java虚拟机调用最初创建该类的类加载器的loadClass方法。

例如,应用程序可以创建一个网络类加载器来从服务器下载类文件。 示例代码可能如下所示:
ClassLoader loader = new NetworkClassLoader(host, port);
Object main = loader.loadClass(“Main”, true).newInstance();
. . .

  1. 网络类加载器子类必须定义方法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
           . . .
      }
    

    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值