14-ClassLoader源码分析与实例剖析

ClassLoader源码分析与实例剖析

​ public abstract class ClassLoader extends Object

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

​ 类加载器是负责加载类的对象。类加载器是是一个抽象类。给定类的二进制名称,类加载器应尝试查找(定位)或生成构成类定义的数据。典型的策略是将名称转换为文件名,然后从文件系统中读取该名称的“类文件”。

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

​ 每个Class对象都包含对定义它的类加载器的引用。

​ Class objects for array classes are not created by class loaders, but are created automatically as required by the Java runtime. 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对象不是由类加载器创建的,而是根据Java运行时的需要自动创建的。对于数组的类加载器来说,Class.getClassLoader()返回的数组类的类加载器与它的元素类型的类加载器相同;如果元素类型是基本类型,则数组类没有类加载器。【具体验证看实例一】

​ 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 类使用委托机制来搜索类和资源。类加载器的每个实例都有一个关联的父类加载器。当请求查找类或资源时,类加载器实例将在试图查找类或资源本身之前,将对该类或资源的搜索委托给其父类加载器。虚拟机的内置类加载器称为“引导(根)类加载器”,它本身没有父类,但可以用作类加载器实例的父类。

​ 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.registeraspallelable方法来注册它们自己。注意,默认情况下ClassLoader类注册为parallel-capable(有并行能力)。但是,如果其子类具有并行能力,则仍需要注册它们自己(也就是说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).

​ 在委托机制不是严格分层的环境中,类加载器需要具有并行能力,否则类装入可能导致死锁,因为加载器锁在类加载过程的持续时间内保持不变(就是说,加载器在类加载过程中一直持有锁)(请参阅loadClass方法)。

​ 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方法将字节数组转换为类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:

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

Binary names:
Any class name provided as a String parameter to methods in ClassLoader must be a binary name as defined by The Java™ Language Specification.
Examples of valid class names include:

​ 作为字符串参数提供给类加载器中的方法的任何类名都必须是由Java™语言规范定义的二进制名称。

​ 有效类名的示例包括:

"java.lang.String"
"javax.swing.JSpinner$DefaultEditor"
"java.security.KeyStore$Builder$FileBuilder$1"
"java.net.URLClassLoader$3$1"
  • 实例一:

    public class MyTest15 {
        public static void main(String[] args) {
            String[] strings = new String[2];
            System.out.println(strings.getClass().getClassLoader());
    
            System.out.println("-----------------");
    
            MyTest15[] myTest15s = new MyTest15[2];
            System.out.println(myTest15s.getClass().getClassLoader());
    
            System.out.println("-----------------");
    
            int[] ints = new int[2];
            System.out.println(ints.getClass().getClassLoader());
        }
    }
    运行结果:
          null     //这个null是根类加载器,并不是没有加载器
          -----------------
          sun.misc.Launcher$AppClassLoader@18b4aac2
          -----------------
          null	   //这个null是没有加载器,因为int是基本类型
    
发布了12 篇原创文章 · 获赞 0 · 访问量 190

猜你喜欢

转载自blog.csdn.net/qq_40574305/article/details/104784596
今日推荐