jvm原理(9)ClassLoader源碼分析與實例剖析

本文轉載自:http://www.javaxxz.com/thread-359190-1-1.htmlphp

public abstract class ClassLoader extends Objecthtml

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

一個類加載器是用於加載類的這麼一個對象,ClassLoader是一個抽象類,給定一個二進制的名字,類加載器應該嘗試定位(找到類定義數據的位置)和生成(動態代理就是動態生成的)構成了這個類定義的數據,一個典型的策略就是將一個名字裝換爲一個文件名字,以後從文件系統讀取這個文件包含的字節碼。 
Every Class object contains a reference to the ClassLoader that defined it. 
任何一個類都有一個定義這個類的ClassLoader的引用bootstrap

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運行時在須要的時候自動建立【回顧:http://blog.csdn.net/wzq6578702/article/details/79370662】 
對於數組的類加載器來講,經過Class.getClassLoader() 返回的和數組元素的類型類加載器是同樣的,若是數組的元素是原生類型的, 
那麼這個數組是沒有類加載器的。 
舉例:數組

public class MyTest15 {
    public static void main(String[] args) {
        String[] strings = new String[2];
        System.out.println(strings.getClass().getClassLoader());

        MyTest15[] myTest15s = new MyTest15[2];
        System.out.println(myTest15s.getClass().getClassLoader());

        int [] ints = new int[2];
        System.out.println(ints.getClass().getClassLoader());

        HashMap[] maps = new HashMap[2];
        System.out.println(maps.getClass().getClassLoader());
    }
}安全

輸出:網絡

null 【這個null指的是根類加載器】
sun.misc.Launcher$AppClassLoader@18b4aac2  【數組的加載器和數組元素扥加載器同樣】
null 【指的是沒有類加載器】
null  【這個null指的是根類加載器】併發

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 實例在它本身發現類或者資源自己以前會委託他的父級類加載器去加載類或者發現資源。虛擬機內建的類加載器成爲「啓動類加載器」,它自己是沒有雙親的,可是他自己能夠做爲一個類加載器的雙親。 
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). 
在委託模型並非嚴格的層次化的環境下,類加載器是須要並行的,不然類加載過程當中是會死鎖的,由於類加載的過程當中是持有鎖的(查看getClass方法) 
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: 
舉例,一個應用經過網絡類加載器從網絡上的一個服務來下載class文件,實例代碼就像這樣: 
ClassLoader loader = new NetworkClassLoader(host, port); 
Object main = loader.loadClass(「Main」, true).newInstance(); 
app

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: 
網絡加載器的子類必須定義loadClassData 和findClass方法來從網絡加載class,一旦下載完畢類的字節碼就會構建這個class,他須要使用defineClass 方法來建立一個類的實例,一個實現的實例: 
class NetworkClassLoader extends ClassLoader { 
String host; 
int port;dom

     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. 
二進制名字 
任何類的名字都是經過字符串的形式,做爲類加載器的方法的參數,稱之爲二進制的名字,這是Java虛擬機規範制定的。 
Examples of valid class names include: 
二進制名字舉例  「java.lang.String」 【String類】  「javax.swing.JSpinner<span class="MathJax" id="MathJax-Element-4-Frame" tabindex="0" data-mathml="DefaultEditor」【DefaultEditor是在JSpinner的內部類】「java.security.KeyStore" role="presentation" style="outline: 0px; position: relative;">DefaultEditor」【DefaultEditor是在JSpinner的內部類】「java.security.KeyStore D e f a u l t E di t o r 」 【 D e f a u l t E d i t o r 是 在 J S p i n n e r 的 內 部 類 】 「 j a v a . s e c u r i t y . K e y S t o r e Builder<span class="MathJax" id="MathJax-Element-5-Frame" tabindex="0" data-mathml="FileBuilder" role="presentation" style="outline: 0px; position: relative;">FileBuilder F i l e B u i l d e r 1」【KeyStore裏邊的內部類Builder的內部類FileBuilder裏邊的第一個匿名內部類】  「java.net.URLClassLoader<span class="MathJax" id="MathJax-Element-6-Frame" tabindex="0" data-mathml="3" role="presentation" style="outline: 0px; position: relative;"> 3 3 1」【URLClassLoader裏邊的第三個匿名內部類裏邊的第一個匿名內部類】

相關文章
相關標籤/搜索