JVM中類的生命週期包括7個階段,加載、準備、驗證、解析、初始化、使用、卸載。其中準備、驗證、解析被歸爲鏈接階段。java
jvm在這個階段完成的工做數據結構
java.lang.class
對象,做爲訪問類在方法區中數據的入口在這個階段開發者能夠控制二進制字節流的獲取,也就是能夠經過自定義的類加載器作本身定製化的操做。jvm
顧名思義,驗證被加載的類的正確性。ide
爲類的 靜態變量分配內存,並將其初始化爲默認值spa
final static
修飾的變量則會賦值爲代碼中的初始值(即:final static int val=3,這時val賦值爲3,而不是0)把類中的符號引用轉換爲直接引用符號引用就是一組符號來描述目標(例如:ArrayList)。直接引用就是直接指向目標的指針、相對偏移量或一個間接定位到目標的句柄。指針
類變量的初始化code
觸發類初始化的場景對象
sun.misc.Launcher$ExtClassLoader
,它負責加載 jrelibext目錄中,或者由 java.ext.dirs系統變量指定的路徑中的全部類庫。開發者能夠直接使用。sun.misc.Launcher$AppClassLoader
,它負責加載用戶類路徑(ClassPath)所指定的類。開發者能夠直接使用雙親委派模型的實現,當一個類加載器須要加載類時,會把這個任務委派給父級類加載器,依次向上,倒頂層啓動類加載器爲止,若是父級沒法加載,再本身處理加載。雙親委派模型的好處是,保證同一類環境中只有一個相同的類。也就是說JVM中判斷是不是同一個類的條件是,是否相同的類加載器,類自己相同。代碼示例:生命週期
public class ClassLoaderTest { public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException { // 使用ClassLoaderTest的類加載器加載本類 Object obj1 = ClassLoaderTest.class.getClassLoader().loadClass("com.ognice.ClassLoaderTest").newInstance(); System.out.println(obj1.getClass().getClassLoader()); System.out.println(obj1 instanceof ClassLoaderTest); // 使用自定義類加載器加載本類 ClassLoader customClassLoader = new ClassLoader() { @Override public Class<?> loadClass(String name) throws ClassNotFoundException { System.out.println("custom classloader loading " + name); String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class"; InputStream stream = getClass().getResourceAsStream(fileName); if (stream == null) { return super.loadClass(name); } try { byte[] b = new byte[stream.available()]; stream.read(b); return defineClass(name, b, 0, b.length); } catch (IOException e) { e.printStackTrace(); } // 父級找class return super.loadClass(name); } }; Object obj2 = customClassLoader.loadClass("com.ognice.ClassLoaderTest").newInstance(); System.out.println(obj2.getClass().getClassLoader()); System.out.println(obj2 instanceof ClassLoaderTest); } }
執行結果內存
sun.misc.Launcher$AppClassLoader@18b4aac2 true custom classloader loading com.ognice.ClassLoaderTest custom classloader loading java.lang.Object custom classloader loading java.lang.ClassLoader custom classloader loading com.ognice.ClassLoaderTest$1 com.ognice.ClassLoaderTest$1@277c0f21 false