【Java虚拟机7】ClassLoader源码文档翻译
前言
学习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源码文档翻译的更多相关文章
- 别翻了,这篇文章绝对让你深刻理解java类的加载以及ClassLoader源码分析【JVM篇二】
目录 1.什么是类的加载(类初始化) 2.类的生命周期 3.接口的加载过程 4.解开开篇的面试题 5.理解首次主动使用 6.类加载器 7.关于命名空间 8.JVM类加载机制 9.双亲委派模型 10.C ...
- JVM 类加载器ClassLoader源码学习笔记
类加载 在Java代码中,类型的加载.连接与初始化过程都是在程序运行期间完成的. 类型可以是Class,Interface, 枚举等. Java虚拟机与程序的生命周期 在如下几种情况下,Java虚拟机 ...
- JAVA上百实例源码以及开源项目
简介 笔者当初为了学习JAVA,收集了很多经典源码,源码难易程度分为初级.中级.高级等,详情看源码列表,需要的可以直接下载! 这些源码反映了那时那景笔者对未来的盲目,对代码的热情.执着,对IT的憧憬. ...
- JAVA上百实例源码网站
JAVA源码包1JAVA源码包2JAVA源码包3JAVA源码包4 JAVA开源包1 JAVA开源包2 JAVA开源包3 JAVA开源包4 JAVA开源包5 JAVA开源包6 JAVA开源包7 JAVA ...
- Java集合---Array类源码解析
Java集合---Array类源码解析 ---转自:牛奶.不加糖 一.Arrays.sort()数组排序 Java Arrays中提供了对所有类型的排序.其中主要分为Prim ...
- Java IO 之 OutputStream源码
Writer :BYSocket(泥沙砖瓦浆木匠) 微 博:BYSocket 豆 瓣:BYSocket FaceBook:BYSocket Twitter ...
- java线程池ThreadPoolExector源码分析
java线程池ThreadPoolExector源码分析 今天研究了下ThreadPoolExector源码,大致上总结了以下几点跟大家分享下: 一.ThreadPoolExector几个主要变量 先 ...
- 《java.util.concurrent 包源码阅读》 结束语
<java.util.concurrent 包源码阅读>系列文章已经全部写完了.开始的几篇文章是根据自己的读书笔记整理出来的(当时只阅读了部分的源代码),后面的大部分都是一边读源代码,一边 ...
- 《java.util.concurrent 包源码阅读》13 线程池系列之ThreadPoolExecutor 第三部分
这一部分来说说线程池如何进行状态控制,即线程池的开启和关闭. 先来说说线程池的开启,这部分来看ThreadPoolExecutor构造方法: public ThreadPoolExecutor(int ...
随机推荐
- vue 前端反向代理后台,解决跨域问题
// 和 src 同层的 config 文件夹下的 index.js dev 里面的 // Paths assetsSubDirectory: 'static', assetsPubl ...
- Python - 面向对象编程 - 三大特性之封装
简单介绍封装 封装是面向对象编程的一大特点 封装可以被认为是一个保护屏障,防止该类的属性.方法和数据结构被外部随意访问 要访问该类的属性.私有方法.数据结构,必须由指定的方法控制访问 深入理解封装 在 ...
- ubantu硬盘不足,无法启动
我的ubantu虚拟机经过我一顿操作后,就起不来了.然后经过多方询问,广集天下良方,最终发现是由于分配的硬件空间不足导致的.现象如下: 通过查看 root@ubantu:/snap# df -h Fi ...
- 快速模式第三包收尾之quick_inI2()
快速模式第三包收尾之quick_inI2() 文章目录 快速模式第三包收尾之quick_inI2() 1. 序言 2. quick_inI2()处理流程图 3. 报文格式 4. quick_inI2( ...
- Java单例-双重检查锁
问题引入 Java中实现单例模式,一般性的做法是如下方式: class Singleton { private static Singleton INSTANCE = null; private Si ...
- MySQL查询结果集字符串操作之多行合并与单行分割
前言 我们在做项目写sql语句的时候,是否会遇到这样的场景,就是需要把查询出来的多列,按照字符串分割合并成一列显示,或者把存在数据库里面用逗号分隔的一列,查询分成多列呢,常见场景有,文章标签,需要吧查 ...
- Sonarqube C# 配置资料整理
c#配置方式: http://www.cnblogs.com/CoderAyu/p/9416376.html http://www.cnblogs.com/jingridong/p/6513884.h ...
- 一键配置tomcat定期日志清理功能
概述 日志文件包含了关于系统中发生的事件的有用信息,在排障过程中或者系统性能分析时经常被用到.对于忙碌的服务器,日志文件大小会增长极快,服务器会很快消耗磁盘空间,这成了个问题.除此之外,处理一个单个的 ...
- Learning How to Learn 学习如何学习
Introduction 这是 UCSD 开设在 Coursera 上的课程 Learning How to Learn 的课程笔记.这门课程主要基于神经科学和认知心理学的一些研究成果讲述高效学习的理 ...
- 多线程run()方法是不能够被直接调用的
操作系统线程的五种状态: 1.新建状态(New):新创建了一个线程对象. 2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于"可运行 ...