反射(java)

類加載時機

當程序要使用某個類時,如果該類還未柏加載到內存中系統就會通過加載,連接,初始化三步來實現對這個類進行初始化。

加載:將class文件讀入內存,併爲之創建一個class對象。任何類被使用時系統都會建立一個class對象。

連接:驗證是否有正確的內部結構,並和其他類協調一致;準備 負責爲類的靜態成員分配內存,並設置默認初始化值。

初始化:初始化成員變量...

類的加載器(ClassLoader)

概念:負責將.class文件加載到內存中,併爲之生成對應的class對象。

反射

創建一個對象的三個階段:1.源文件階段.java文件;2.字節碼階段.class;3.創建對象階段 new 對象名稱。

內省:在運行的時候能夠獲取javaBean當中的屬性名稱和get與set方法。

反射:java反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取信息以及動態調用對象的方法稱爲java語言的反射機制。使用反射之前要獲取字節碼文件。

獲取字節碼文件:Object類的getClass()方法【判斷兩個對象是否是同一個字節碼文件】;靜態屬性Class【當作靜態方法鎖定對象】;Class類中靜態方法forName()【讀取配置文件】

Class<?> clazz1 = Class.forName("com.helong.sevlet.MyServlet");
Class clazz2 = MyServlet.class;
MyServlet s = new MyServlet();
Class clazz3 = s.getClass();

通過字節碼來獲取對象

1.通過無參構造創建對象

//1.獲取字節碼
Class<?> clazz1 = Class.forName("com.helong.Servlet.MyServlet");
//2.通過字節碼來創建字節碼對象
MyServlet s = (MyServlet)clazz1.newInstance();
//3.操作通過字節碼創建的對象
s.name = "zs";
s.show();

 2.通過有參構造來創建對象

Class clazz = Class.forName("com.helong.reflect.Person");
//1.獲取字節碼構造器:clazz.getConstructor(type.class);
//因爲在反射階段操作的都是字節碼,不知道具體是什麼類型,只有在創建對象的時候纔去給實際參數
Constructor  c = clazz.getConstructor(String.class,Integer.class);
//2.創建對象並傳入參數
Person p = (Person)c.newInstance("何鑫林",10);
//3.調用方法
p.show();

 獲取字段

1.獲取公共的字段

Class clazz = Class<?> clazz1 = Class.forName("com.helong.reflect.Person");
Person p = (Person)clazz.newInstance();
Filed f = clazz.getField("name");
f.set(p,"zs");
System.out.println(p);

 2.獲取私有字段

Class clazz = Class.forName("com.helong.reflect.Person");
Person per = (Person)clazz.newInstance();
//暴力反射獲取字段
Filed f = clazz.getDeclaredField("age");
//去除私有權限
f.setAccessible(true);
f.set(per,20);
System.out.println(per);

 獲取方法

Class clazz = Class.forName("com.helong.reflect.Perosn");
Person per = (Person)clazz.newInstace();
Method m = clazz.getMethod("show");
m.invoke(per);

Method m2 = clazz.getDeclaredMethod("eat",String.class);
m2.setAccessible(true);
m2.invoke(per,"rice");

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章