咱們注意到若是沒有靜態變量c,那麼字節碼文件中就不會有clinit方法
/**
* ClassLoader加載
*/
public class ClassLoaderTest {
public static void main(String[] args) {
//獲取系統類加載器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2
//獲取其上層 擴展類加載器
ClassLoader extClassLoader = systemClassLoader.getParent();
System.out.println(extClassLoader);//sun.misc.Launcher$ExtClassLoader@610455d6
//獲取其上層 獲取不到引導類加載器
ClassLoader bootStrapClassLoader = extClassLoader.getParent();
System.out.println(bootStrapClassLoader);//null
//對於用戶自定義類來講:使用系統類加載器進行加載
ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
System.out.println(classLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2
//String 類使用引導類加載器進行加載的 -->java核心類庫都是使用引導類加載器加載的
ClassLoader classLoader1 = String.class.getClassLoader();
System.out.println(classLoader1);//null
}
}
複製代碼
/**
* 虛擬機自帶加載器
*/
public class ClassLoaderTest1 {
public static void main(String[] args) {
System.out.println("********啓動類加載器*********");
URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
//獲取BootStrapClassLoader可以加載的api路徑
for (URL e:urls){
System.out.println(e.toExternalForm());
}
//從上面的路徑中隨意選擇一個類 看看他的類加載器是什麼
//Provider位於 /jdk1.8.0_171.jdk/Contents/Home/jre/lib/jsse.jar 下,引導類加載器加載它
ClassLoader classLoader = Provider.class.getClassLoader();
System.out.println(classLoader);//null
System.out.println("********拓展類加載器********");
String extDirs = System.getProperty("java.ext.dirs");
for (String path : extDirs.split(";")){
System.out.println(path);
}
//從上面的路徑中隨意選擇一個類 看看他的類加載器是什麼:拓展類加載器
ClassLoader classLoader1 = CurveDB.class.getClassLoader();
System.out.println(classLoader1);//sun.misc.Launcher$ExtClassLoader@4dc63996
}
}
複製代碼
爲何html
方法名稱 | 描述 |
---|---|
getParent() | 返回該類加載器的超類加載器 |
loadClass(String name) | 加載名稱爲name的類,返回結果爲java.lang.Class類的實例 |
findClass(String name) | 查找名稱爲name的類,返回結果爲java.lang.Class類的實例 |
findLoadedClass(String name) | 查找名稱爲name的已經被加載過的類,返回結果爲java.lang.Class類的實例 |
defineClass(String name,byte[] b,int off,int len) | 把字節數組b中的內容轉換爲一個Java類 ,返回結果爲java.lang.Class類的實例 |
resolveClass(Class<?> c) | 鏈接指定的一個java類 |
拓展類加載器和系統類加載器間接繼承於ClassLoader抽象類java
Java虛擬機對class文件採用的是按需加載的方式,也就是說當須要使用該類時纔會將她的class文件加載到內存生成的class對象。並且加載某個類的class文件時,java虛擬機採用的是雙親微拍模式,即把請求交由父類處理,它是一種任務委派 模式git
自定義String類,可是在加載子弟敬意String類的時候回率先使用引導類加載器加載,而引導類加載器在加載過程當中會先加載jdk自帶的文件(rt.jar包中的java\lang\String.class),報錯信息說沒有main方法就是由於加載的是rt.jar包中的String類。這樣能夠保證對java核心源代碼的保護,這就是沙箱安全機制.github
類比舉例: 咱們在讀寫U盤信息時能夠用360沙箱,防止U盤內的病毒等對沙箱外的系統構成污染算法
JVM必須知道一個類型是有啓動類加載器加載的仍是由用戶類加載器加載的。若是一個類型由用戶類加載器加載的,那麼jvm會將這個類加載器的一個引用做爲類型信息的會議部分保存在方法區中。當解析一個類型到另外一個類型的引用的時候,JVM須要保證兩個類型的加載器是相同的。api
java程序對類的使用方式分爲:主動使用和被動使用數組
【代碼】
github.com/willShuhuan…
【筆記】
JVM_01 簡介
JVM_02 類加載子系統
JVM_03 運行時數據區1- [程序計數器+虛擬機棧+本地方法棧]
JVM_04 本地方法接口
JVM_05 運行時數據區2-堆
JVM_06 運行時數據區3-方法區
JVM_07 運行時數據區4-對象的實例化內存佈局與訪問定位+直接內存
JVM_08 執行引擎(Execution Engine)
JVM_09 字符串常量池StringTable
JVM_10 垃圾回收1-概述+相關算法
JVM_11 垃圾回收2-垃圾回收相關概念
JVM_12 垃圾回收3-垃圾回收器安全