前言

学习JVM类加载器,ClassLoader这个类加载器的核心类是必须要重视的。

Notes:下方蓝色文字是自己的翻译(如果有问题请指正)。黑色文字是源文档。红色文字是自己的备注。

ClassLoader类源码文档

public abstract class ClassLoader extends Object

类加载器是一个负责加载类的对象。

A class loader is an object that is responsible for loading classes.

类"ClassLoader"是一个抽象类。

The class ClassLoader is an abstract class.

给定一个类的“binary name”(下方有binary name的解释),类加载器应该尝试定位或生成一些构成类定义的数据。(这里生成是因为可以动态生成类的定义。)

Given the binary name of a class, a class loader should attempt to locate or generate data that constitutes a definition for the class.

一种典型的策略是将这个给定的二进制名字转换成一个文件系统的名字,然后去读取这个class文件。

A typical strategy is to transform the name into a file name and then read a "class file" of that name from a file system.

每一个Class对象都包含一个加载它的ClassLoader的引用。(如String.class.getClassLoader()

Every Class object contains a reference to the ClassLoader that defined it.

数组类的Class对象不是被class loader创建的,而是被Java运行时环境自动创建的。

Class objects for array classes are not created by class loaders, but are created automatically as required by the Java runtime.

对于数组类型的class loader对象是和数组内部的element类型的class loader是同一个。(比如说String[]的类加载器就等于String的类加载器,同为根类加载器。)

The class loader for an array class, as returned by Class.getClassLoader() is the same as the class loader for its element type;

如果数组中的元素是一个原始类型,那么这个数组是没有class loader的。

if the element type is a primitive type, then the array class has no class loader.

客户应用可以实现ClassLoader类来扩展一种JVM动态加载类的方式。(这句话就是自定义加载器的作用,你自己写类加载器就是用来动态加载类的)

Applications implement subclasses of ClassLoader in order to extend the manner in which the Java virtual machine dynamically loads classes.

类加载器一般会被security managers所使用,用来标识一些安全域范围。

Class loaders may typically be used by security managers to indicate security domains.

ClassLoader类使用了一种委托模型来寻找类和资源。

The ClassLoader class uses a delegation model to search for classes and resources.

ClassLoader类的每一个实例都会有一个与之关联的parent class loader

Each instance of ClassLoader has an associated parent class loader.

当我们向一个class loader发起请求查找一个class或者资源的时候,在这个ClassLoader查找之前,它会先将这个查找请求委托给它的parent class loader来执行。

When requested to find a class or resource, a ClassLoader instance will delegate the search for the class or resource to its parent class loader before attempting to find the class or resource itself.

虚拟机内嵌的类加载器,我们称为"bootstrap class loader",它没有parent class loader,但是它可以作为其他类加载器的双亲。

The virtual machine's built-in class loader, called the "bootstrap class loader", does not itself have a parent but may serve as the parent of a ClassLoader instance.

支持并行的类加载器称为"parallel capable class loaders",它被要求在它自己初始化期间,它需要通过调用ClassLoader.registerAsParallelCapable()方法来把自己注册成并行类加载器。

Class loaders that support concurrent loading of classes are known as parallel capable class loaders and are required to register themselves at their class initialization time by invoking the ClassLoader.registerAsParallelCapable method.

ClassLoader类默认被注册成为一个"parallel capable class loaders"

Note that the ClassLoader class is registered as parallel capable by default.

但是,它的子类依然需要自己注册成"parallel capable class loaders"

However, its subclasses still need to register themselves if they are parallel capable.

在委托模型并非严格层次化的模型下,类加载器是需要支持并行的,否则类加载可能会导致死锁,因为加载器的锁是在整个加载过程中都被占有的。

In environments in which the delegation model is not strictly hierarchical, class loaders need to be parallel capable, otherwise class loading can lead to deadlocks because the loader lock is held for the duration of the class loading process (see loadClass methods).

通常情况下,JVM是以一种平台无关的从本地文件系统加载类。例如,在UNIX系统中,虚拟机从CLASSPATH环境变量中加载类。

Normally, the Java virtual machine loads classes from the local file system in a platform-dependent manner.

For example, on UNIX systems, the virtual machine loads classes from the directory defined by the CLASSPATH environment variable.

然后,有些类并不是来自于文件系统,而是来自于其他地方,如网络或者其二进制码是由应用自己生成的。

However, some classes may not originate from a file; they may originate from other sources, such as the network, or they could be constructed by an application.

在这种情况下,"defineClass"会将字节数组转换为一个Class类的实例。这个新定义的类的实例是可以由Class.newInstance来创建的。

The method defineClass converts an array of bytes into an instance of class Class. Instances of this newly defined class can be created using Class.newInstance.

由类加载创建的对象的方法和构造器可能会引用其他类。

The methods and constructors of objects created by a class loader may reference other classes.

为了确认“被引用的类”(假设为A类)都是什么类,虚拟机会调用创建这个类的class loader的loadClass方法,来加载这个类。

To determine the class(es) referred to, the Java virtual machine invokes the loadClass method of the class loader that originally created the class.



上面2句比较难以理解,举个例子,一个MySample类的构造器和一个MyCat类的构造器方法中,本没有关系,new MySample()中会new MyCat(),此时就是MySample引用了MyCat类。

所以这里“被引用的类”就是MyCat,MySample会先被加载,然后加载MyCat的时候,JVM会使用MySample的类加载器来加载MyCat。

例如,一个应用可以创建一个网络类加载器来从远程服务器下载字节码文件。

For example, an application could create a network class loader to download class files from a server.

示例代码如下:

Sample code might look like:

   ClassLoader loader = new NetworkClassLoader(host, port);
Object main = loader.loadClass("Main", true).newInstance();
...

network class loader必须要定义findClass和loadClassData方法来从网络上加载类。

The network class loader subclass must define the methods findClass and loadClassData to load a class from the network.

一旦下载字节码文件完成,需要调用defineClass来创建一个Class类实例。

Once it has downloaded the bytes that make up the class, it should use the method defineClass to create a class instance.

示例代码如下:

A sample implementation is:

 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
. . .
}
}

Binary names

对ClassLoader类中的方法参数来说,如果这个参数是代表class名字,那么这个名字必须是一个binary name(二进制名字)。这个二进制名字是被JLS定义的。

Any class name provided as a String parameter to methods in ClassLoader must be a binary name as defined by The Java Language Specification.

如下:binary name(二进制名字)类名需要给全路径,中间用点号分割,如果有内部类使用"$"分割,如果有匿名内部类,按顺序使用"$ + 数字"代表

Examples of valid class names include:

"java.lang.String"

"javax.swing.JSpinner$DefaultEditor"

"java.security.KeyStore$Builder$FileBuilder$1"

"java.net.URLClassLoader$3$1"

ClassLoader方法源码文档

getSystemClassLoader()

返回一个用于委托的系统类加载器。它是新的ClassLoader实例的默认的委托双亲,它通常是用来启动应用的类加载器。

Returns the system class loader for delegation. This is the default delegation parent for new ClassLoader instances, and is typically the class loader used to start the application.

getSystemClassLoader()这个方法最早在JVM运行时的启动阶段中被第一次调用,在此调用时,它会创建系统类加载器并且会将它设置为调用这个方法的当前线程的上下文类加载器。

这也是为什么:Thread.currentThread().getContextClassLoader()用来获取当前线程上下文的ClassLoader,一般为系统类加载器。

This method is first invoked early in the runtime's startup sequence, at which point it creates the system class loader and sets it as the context class loader of the invoking Thread.

默认的系统类加载器是一个与这个类实现相关的的实例。

The default system class loader is an implementation-dependent instance of this class.

当这个方法第一次被调用的时候,如果系统属性“java.system.class.loader”被定义了,那么这个属性的值就会被作为系统类加载器的名字了。

“java.system.class.loader”这个被设置的值肯定是一个类的二进制名。我称它为“被设置的系统类加载器类”。

If the system property "java.system.class.loader" is defined when this method is first invoked then the value of that property is taken to be the name of a class that will be returned as the system class loader.

“被设置的系统类加载器类”是被默认系统类加载器加载的,这个“被设置的系统类加载器类”必须定义一个public的接受一个ClassLoader参数的构造器,这个参数的值会被作为委托双亲。

The class is loaded using the default system class loader and must define a public constructor that takes a single parameter of type ClassLoader which is used as the delegation parent.

接下来一个实例会被默认的系统类加载器调用刚才那个构造器创建。得到的class loader就会被定义为系统类加载器。

An instance is then created using this constructor with the default system class loader as the parameter. The resulting class loader is defined to be the system class loader.

上面这一段要注意默认系统类加载器的作用。我们可以通过修改系统属性"java.system.class.loader"修改系统类加载器。这是虚拟机提供给我们的一个功能。

系统属性"java.system.class.loader"默认是null,没有定义。

如果存在安全管理器,并且调用方的类加载器不为null,并且调用方的类加载器与系统类加载器不同或没有双亲的关系,则此方法使用RuntimePermission(“getClassLoader”)权限调用安全管理器的checkPermission方法,以验证对系统类加载器的访问。否则,将抛出SecurityException。

If a security manager is present, and the invoker's class loader is not null and the invoker's class loader is not the same as or an ancestor of the system class loader, then this method invokes the security manager's checkPermission method with a RuntimePermission("getClassLoader") permission to verify access to the system class loader. If not, a SecurityException will be thrown.

返回值:双亲委托的系统类加载器,或者是null。

Returns:

The system ClassLoader for delegation, or null if none

【Java虚拟机7】ClassLoader源码文档翻译的更多相关文章

  1. 别翻了,这篇文章绝对让你深刻理解java类的加载以及ClassLoader源码分析【JVM篇二】

    目录 1.什么是类的加载(类初始化) 2.类的生命周期 3.接口的加载过程 4.解开开篇的面试题 5.理解首次主动使用 6.类加载器 7.关于命名空间 8.JVM类加载机制 9.双亲委派模型 10.C ...

  2. JVM 类加载器ClassLoader源码学习笔记

    类加载 在Java代码中,类型的加载.连接与初始化过程都是在程序运行期间完成的. 类型可以是Class,Interface, 枚举等. Java虚拟机与程序的生命周期 在如下几种情况下,Java虚拟机 ...

  3. JAVA上百实例源码以及开源项目

    简介 笔者当初为了学习JAVA,收集了很多经典源码,源码难易程度分为初级.中级.高级等,详情看源码列表,需要的可以直接下载! 这些源码反映了那时那景笔者对未来的盲目,对代码的热情.执着,对IT的憧憬. ...

  4. JAVA上百实例源码网站

    JAVA源码包1JAVA源码包2JAVA源码包3JAVA源码包4 JAVA开源包1 JAVA开源包2 JAVA开源包3 JAVA开源包4 JAVA开源包5 JAVA开源包6 JAVA开源包7 JAVA ...

  5. Java集合---Array类源码解析

    Java集合---Array类源码解析              ---转自:牛奶.不加糖 一.Arrays.sort()数组排序 Java Arrays中提供了对所有类型的排序.其中主要分为Prim ...

  6. Java IO 之 OutputStream源码

    Writer      :BYSocket(泥沙砖瓦浆木匠) 微         博:BYSocket 豆         瓣:BYSocket FaceBook:BYSocket Twitter   ...

  7. java线程池ThreadPoolExector源码分析

    java线程池ThreadPoolExector源码分析 今天研究了下ThreadPoolExector源码,大致上总结了以下几点跟大家分享下: 一.ThreadPoolExector几个主要变量 先 ...

  8. 《java.util.concurrent 包源码阅读》 结束语

    <java.util.concurrent 包源码阅读>系列文章已经全部写完了.开始的几篇文章是根据自己的读书笔记整理出来的(当时只阅读了部分的源代码),后面的大部分都是一边读源代码,一边 ...

  9. 《java.util.concurrent 包源码阅读》13 线程池系列之ThreadPoolExecutor 第三部分

    这一部分来说说线程池如何进行状态控制,即线程池的开启和关闭. 先来说说线程池的开启,这部分来看ThreadPoolExecutor构造方法: public ThreadPoolExecutor(int ...

随机推荐

  1. Linux常用命令 - head命令详解

    21篇测试必备的Linux常用命令,每天敲一篇,每次敲三遍,每月一循环,全都可记住!! https://www.cnblogs.com/poloyy/category/1672457.html 显示文 ...

  2. Git 系列教程(11)- 分支简介

    前言 很多版本控制系统都有分支这个概念 使用分支意味着可以将日常工作从主线上脱离,从而避免影响主线 Git 鼓励在工作流程中频繁使用分支和合并 Git 是如何保存数据的 Git 保存的不是文件的变化或 ...

  3. java 集合特性面试必备

    collection 集合体系 数据结构栈和队列栈结构 :先进后出队列结构 :先进先出 数据结构之数组和链表数组结构:查询快.增删慢队列结构 :查询慢.增删快 List集合概述有序集合(也称为序列), ...

  4. openswan协商流程之(五):main_inR2_outI3()

    主模式第五包:main_inR2_outI3 文章目录 主模式第五包:main_inR2_outI3 1. 序言 2.函数调用关系 3. 第五个报文流程图 4. main_inR2_outI3()源码 ...

  5. 数据结构(c++)(第二版) Dijkstra最短路径算法 教学示范代码出现重大问题!

    前言 去年在数据结构(c++)的Dijkstra教学算法案例中,发现了一个 bug 导致算法不能正常的运行,出错代码只是4行的for循环迭代代码. 看到那里就觉得有问题,但书中只给了关键代码的部分,其 ...

  6. Stream流方法引用

    一.对象存在,方法也存在,双冒号引用 1.方法引用的概念: 使用实例: 1.1先定义i一个函数式接口: 1.2定义一个入参参数列表有函数式接口的方法: 1.3调用这个入参有函数式接口的方法: lamb ...

  7. RabbitMQ-TTL-死信队列_DLX

    1. 简介 死信队列,简称:DLX,Dead Letter Exchange(死信交换机),当消息成为Dead message后,可以被重新发送到另外一个交换机,这个交换机就是DLX. (一般会将DL ...

  8. 从零开始学习SQL SERVER(1)--- 了解SQL

    SQL是什么 SQL (发音为 sequal ['  sikwəl ' ]) SQL指 Structured Query Language 结构化查询语言,是用于访问和处理数据库的标准的计算机语言. ...

  9. 通过Kubernetes监控探索应用架构,发现预期外的流量

    大家好,我是阿里云云原生应用平台的炎寻,很高兴能和大家一起在 Kubernetes 监控系列公开课上进行交流.本次公开课期望能够给大家在 Kubernetes 容器化环境中快速发现和定位问题带来新的解 ...

  10. 关于vue-cli的安装

    (一):*安装 vue-cli 参考: https://cn.vuejs.org/v2/guide/installation.html https://github.com/vuejs/vue-cli ...