當程序要使用某個類時,若是該類還未被加載到內存中,則系統會經過加載,鏈接,初始化三步來實現對這個類進行初始化。java
加載數組
就是指將class文件讀入內存,併爲之建立一個Class對象。安全
任何類被使用時系統都會創建一個Class對象oracle
鏈接ide
驗證 是否有正確的內部結構,並和其餘類協調一致this
準備 負責爲類的靜態成員分配內存,並設置默認初始化值spa
解析 將類的二進制數據中的符號引用替換爲直接引用code
初始化對象
就是咱們之前講過的初始化步驟blog
1. 建立類的實例
2. 類的靜態變量,或者爲靜態變量賦值
3. 類的靜態方法
4. 使用反射方式來強制建立某個類或接口對應的java.lang.Class對象
5. 初始化某個類的子類
6. 直接使用java.exe命令來運行某個主類
負責將.class文件加載到內存中,併爲之生成對應的Class對象。
雖然咱們不須要關心類加載機制,可是瞭解這個機制咱們就能更好的理解程序的運行
Bootstrap ClassLoader 根類加載器
也被稱爲引導類加載器,負責Java核心類的加載
好比System,String等。在JDK中JRE的lib目錄下rt.jar文件中
Extension ClassLoader 擴展類加載器
負責JRE的擴展目錄中jar包的加載。
在JDK中JRE的lib目錄下ext目錄
System ClassLoader 系統類加載器
代碼演示:
1 public class Person { 2 public String name; 3 private int age; 4 public Person(){ 5 System.out.println("公共構造方法"); 6 } 7 public Person(String name,int age){ 8 this.name=name; 9 this.age=age; 10 System.out.println("公共有參構造"); 11 } 12 private Person(int age,String name){ 13 System.out.println("私有有參構造"); 14 } 15 public void eat(){ 16 System.out.println("公共方法"); 17 } 18 public void sleep(String name){ 19 System.out.println(name+"公共有參方法"); 20 } 21 private void playGames(){ 22 System.out.println("私有方法"); 23 } 24 @Override 25 public String toString() { 26 return "Person [name=" + name + ", age=" + age + "]"; 27 } 28 29 }
1 //獲取字節碼文件對象的三種方式 2 public static void method1() throws ClassNotFoundException{ 3 //1.經過對象獲取 4 Person p=new Person(); 5 Class c=p.getClass(); 6 System.out.println(c); 7 //2.經過類名獲取 8 Class c1=Person.class; 9 System.out.println(c1); 10 System.out.println(c==c1); 11 System.out.println(c.equals(c1)); 12 //3.經過Class類的靜態方法forName(包名.類名)獲取 13 Class c2=Class.forName("com.oracle.demo03.Person"); 14 System.out.println(c2); 15 }
1 //獲取構造方法 2 public static void method2() throws Exception{ 3 //獲取字節碼文件對象 4 Class c=Class.forName("com.oracle.demo03.Person"); 5 //獲取非私有構造方法數組 6 /*Constructor[] cons=c.getConstructors(); 7 for(Constructor con:cons){ 8 System.out.println(con); 9 }*/ 10 /* //獲取空參構造 11 Constructor con=c.getConstructor(); 12 //使用空參構造建立對象 13 Object obj=con.newInstance(); 14 Person p=(Person)obj; 15 p.eat();*/ 16 //獲取有參構造方法並調用 17 /*Constructor con=c.getConstructor(String.class,int.class); 18 Object obj=con.newInstance("張三",18); 19 System.out.println(obj);*/ 20 //針對空參構造有一個快速建立對象的方式 21 //1.Person類中必須有空參構造方法 22 //2.空參構造方法必須是public修飾 23 Object obj=c.newInstance(); 24 System.out.println(obj); 25 }
1. 獲取到Class對象
2. 獲取指定的構造方法
3. 經過構造方法類Constructor中的方法,建立對象
public T newInstance(Object... initargs)
代碼展現:
1 //經過反射獲取私有構造---暴力反射 不推薦使用 2 //它破壞了咱們程序的封裝性、安全性 3 //搶銀行方式 4 public static void method3()throws Exception{ 5 //獲取字節碼文件對象 6 Class c=Class.forName("com.oracle.demo03.Person"); 7 //獲取全部構造方法 8 /*Constructor[] cons=c.getDeclaredConstructors(); 9 for(Constructor con:cons){ 10 System.out.println(con); 11 }*/ 12 //獲取私有構造方法並使用 13 Constructor con=c.getDeclaredConstructor(int.class,String.class); 14 //取消Java對個人檢查 15 con.setAccessible(true); 16 Object obj=con.newInstance(18,"李四"); 17 System.out.println(obj); 18 } 19 public static void method4() throws Exception{ 20 //獲取字節碼文件對象 21 Class c=Class.forName("com.oracle.demo03.Person"); 22 Object obj=c.newInstance(); 23 //獲取公共成員變量並使用 24 Field field=c.getField("name"); 25 field.set(obj,"張三"); 26 //獲取私有成員變量並使用 27 Field f=c.getDeclaredField("age"); 28 f.setAccessible(true); 29 f.set(obj, 18); 30 System.out.println(obj); 31 //System.out.println(field.get(obj)); 32 } 33 public static void method5() throws Exception{ 34 //獲取字節碼文件對象 35 Class c=Class.forName("com.oracle.demo03.Person"); 36 Object obj=c.newInstance(); 37 //獲取空參的成員方法並運行 38 Method method=c.getMethod("eat"); 39 method.invoke(obj); 40 //獲取有參成員方法並運行 41 Method method1=c.getMethod("sleep", String.class); 42 method1.invoke(obj, "張三"); 43 }
1 public class Demo { 2 3 public static void main(String[] args) throws Exception { 4 //反射配置文件實現 5 //把咱們要運行的類和方法以鍵值對的形式寫在文本中 6 //咱們想要運行哪一個類裏面的方法 只須要改配置文件便可 7 /*步驟: 8 * 1.準備配置文件,鍵值對 9 * 2.IO讀取配置文件,Reader 10 * 3.將文件中的鍵值對保存在Properties集合中,鍵值對就是類和方法名 11 * 4.經過反射獲取指定類的class文件對象 12 * 5.經過class文件對象獲取指定方法 13 * 6.運行方法 14 * */ 15 FileReader fr=new FileReader("src/config.properties"); 16 Properties pro=new Properties(); 17 pro.load(fr); 18 String className=pro.getProperty("className"); 19 String methodName=pro.getProperty("methodName"); 20 Class c=Class.forName(className); 21 Object obj=c.newInstance(); 22 Method method=c.getMethod(methodName); 23 method.invoke(obj); 24 25 }
配置文件:
1 #className=com.oracle.demo04.Person 2 #methodName=eat 3 className=com.oracle.demo04.Student 4 methodName=study 5 className=com.oracle.demo04.Worker 6 methodName=work