十二、ClassLoader文档分析

A class loader is an object that is responsible for loading classes.
The class ClassLoader is an abstract class. Given the binary name of a
class, a class loader should attempt to locate or generate data that
constitutes a definition for the 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.

类加载器是用来加载对象的类。ClassLoader类是一个抽象类。通过给定一个类的二进制名称,类加载器应该尝试去定位或者生成构成这个类的定义的数据。一个典型的策略是将这个二进制名称转换为文件名,然后从文件系统中读取这个名字的class文件。

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

每个Class对象都包含了一个引用,指向定义该Class对象的类加载器。

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

数组类型的Class类不是被类加载器创建的,而是被虚拟机根据需要动态创建。

The class loader for an array class, as returned by
Class.getClassLoader() is the same as the class loader for its element
type; if the element type is a primitive type, then the array class
has no class loader.

对于数组类型的、通过·Class.getClassLoader()获得的类加载器,与其元素的类加载器相同。如果元素类型是原生类型的话,则这个数组没有类加载器。


原生类型指的是八大基本数据类型,不包括其包装类。
例:

public class MyTest16 {
    public static void main(String[] args) {
        String[] strs = new String[2];
        System.out.println(strs.getClass());
        System.out.println(strs.getClass().getClassLoader());
        System.out.println("======");
        MyTest16[] myTest16s = new MyTest16[2];
        System.out.println(myTest16s.getClass());
        System.out.println(myTest16s.getClass().getClassLoader());
        System.out.println("======");
        int[] ints = new int[2];
        System.out.println(ints.getClass());
        System.out.println(ints.getClass().getClassLoader());
        System.out.println("======");
        Integer[] ints2 = new Integer[2];
        System.out.println(ints2.getClass());
        System.out.println(ints2.getClass().getClassLoader());
    }
}

输出结果:

class [Ljava.lang.String;
null
======
class [Lcom.jvm.classloader.MyTest16;
sun.misc.Launcher$AppClassLoader@18b4aac2
======
class [I
null
======
class [Ljava.lang.Integer;
null

分析:
对于String类型数组,因为String是由根类加载器加载的,所以其数组的类加载器也是根类加载器,即null。
对于MyTest16,显然是app。
对于int,因为是基本类型,所以数组没有类加载器,显示null。
对于包装类,逻辑跟string一致。


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

实现了ClassLoader的子类的应用,是为了扩展java虚拟机动态加载类的方式。

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

类加载器典型的引用是被安全管理器用来表明安全域。

The ClassLoader class uses a delegation model to search for classes
and resources. Each instance of ClassLoader has an associated 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. 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.

ClassLoader类使用委托模型去寻找类和资源。每一个ClassLoader的实例都会有一个与之关联的双亲类加载器。当被要求去寻找类或者资源的时候,该ClassLoader实例会在他自己尝试去找类或者资源之前,把这个类和资源的查找委托给其双亲类加载器。虚拟机的内置类加载器,bootstrap class loader,自身没有双亲类加载器,但是可以作为其他加载器的双亲加载器。

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. Note that the
ClassLoader class is registered as parallel capable by default.
However, its subclasses still need to register themselves if they are
parallel capable.

支持并发加载类的类加载器,也叫并行类加载器,在初始化的时候,需要通过调用ClassLoader.registerAsParallelCapable方法去注册。需要注意,默认情况下, ClassLoader这个类是被注册为可以并发加载的。但是,如果其子类也有并行加载的能力的话,依旧需要注册。

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

在委托模型不是严格分层的情况下,类加载应该是并行的,否则可能造成死锁,因为类加载锁在类加载的过程中是一直被持有的。

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.

一般情况下,java虚拟机从本地文件系统加载类是平台相关的。比如,在UNIX系统中,虚拟机会从CLASSPATH环境变量定义的目录去加载类。

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

然而,一些类可能不是从文件产生的;他们可能从别的源产生,比如网络。或者他们被应用本身构建出来的(动态代理)。defineClass方法可以将一个bytes 数组转换为一个Class类的实例。这种新定义的类的实例可以通过Class.newInstance创建出来。

The methods and constructors of objects created by a class loader may
reference other classes. To determine the class(es) referred to, the
Java virtual machine invokes the loadClass method of the class loader
that originally created the class.

由类加载创建的对象的方法和构造方法可能引用其他的类。为了确定被引用的类,java虚拟机会调用最初创建这个类的类加载器的loadClass方法。

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();
          . . .

The network class loader subclass must define the methods findClass
and loadClassData to load a class from the network. 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:

网络类加载器子类,一定要定义findClassloadClassData方法从而从网络上加载类。一旦他下载了组成这个类的字节码defineClass方法去创建Class类的实例。例子如下:

       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、付费专栏及课程。

余额充值