一、反射概述Class
1)反射的基石->Class類,Java程序中的各個Java類屬於同一類事物,描述這類事物的Java類名就是Class,而類是用來描述對象的。
2)衆多的人用一個什麼類表示?衆多的Java類用一個什麼類表示?
①人-Person
②Java類-->Class
3)Person類代表人,它的實例對象就是張三、李四這樣的一個個具體的人。Class類代表Java類,它的各個實例對象又分別對應着什麼呢?
①對應各個類在內存中的字節碼,例如,Person類的字節碼,ArrayList類的字節碼等等
②一個類被類加載器加載到內存中,佔用了一片內存空間,這個空間裏面的內容就是類的字節碼,不同的類的字節碼是不同的 ,所以它們在內存中佔的內容是不同的,這一個一個的空間可以分別用一個個對象來標示,這些對象顯然具有相同的類型,這個類型是什麼了?Class類型
4)如何得到各個字節碼對應的實例對象(Class類型),三種方式:
①類名.class,例如System.class
②對象.getClass(),例如 new Date().getClass();
③Class.for.name(“完整類名”),例如Class.forName(“java.util.Date”);
5)九個預定義的Class實例對象
八個基本數據類型的Class實例和void的實例
6)對反射的理解:
反射:類是對對象的抽象,而反射類Class又是對所有類的抽象,將所有類的共性信息提取出來,組成一個類。或者說,反射類是爲java類服務的,而java類是爲象服務的。
7).Java類用於描述一類事物的共性,該類事物有什麼屬性,沒有什麼屬性,至於這個屬性的值是什麼,則是由這個類的實例對象來確定的。不同的實力對象有不同的屬性值。Java程序中的各個Java類,它們是否屬於同一類事物,是不是可以用一個類來描述這個類事物?這個類的名字就是Class,要注意與小寫class關鍵字的區別哦。Class類描述了哪些方面的信息呢?類的名字,類的訪問屬性,類所屬的包,字段名稱的列表、方法名稱列表,等等。學習反射,首先就要明白Class這個類。
二、反射構造函數Constructor
1)Constructor類代表某個類中的一個構造方法
①得到某個類的所有構造方法:
Constructor[] constructors=Class.forName(“java.lang.String”).getConstructors();
②得到某個類的某一個構造方法:
Constructor constructor=Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);
//獲取方法時要用到參數類型的class對象
③調用構造方法,實例對象:
>通常方式:String str=new String(new StringBuffer(“abc”));
>反射方式:constructor=Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);
String str2=(String)constructor.newInstance(new StringBuffer(“abc”));
//調用構造器對象,要用到上面參數類型對應的實例對象
2)Class.NewInstance()方法:
①String obj=class.forName(“java.lang.String).newInstance()
class-->constructor--->new Object
class->new Object() (內部還是創建了一個默認的構造器對象)
三、反射字段Field
1)創建一個類如下,有私有字段。
public class Point {
private int x;
public int y;
public Point(int x, int y) {
super();
this.x = x;
this.y = y;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return str1+":"+str2+":"+str3;
}
}
2)實現反射公有字段和私有字段
①公有字段
Point p1=new Point(3,5);
Field fy=p1.getClass().getField("y");//返回可訪問字段,封裝了y字段信息的一個對象
/field不是對象上的變量,而是類上的。
System.out.println(fy+":"+fy.get(p1));
②私有字段
Field fx=p1.getClass().getDeclaredField("x");//返回聲明的字段
fx.setAccessible(true);//暴力訪問,可以訪問私有的。
System.out.println(fx+":"+fx.get(p1));
四、反射成員方法Method
1)Method類代表某個類中的成員方法,而Method創建的對象就是具體的某個方法了。
①創建Method類對象,封裝String的CharAt方法
Method methodCharAt=String.class.getMethod("charAt", int.class);
②使用String類對象,調用反射到的CharAt方法
String str1=”張三李四”;
System.out.println(methodCharAt.invoke(str1, 1));
③如果第一個參數爲null,則表示通過Sting類調用其靜態方法。
Method copyValueOf=String.class.getMethod("copyValueOf", char[].class);
System.out.println(copyValueOf.invoke(null, (Object)(new char[]{'a','b','c'})));
五、反射main方法
1)普通調用main的方式
TestArgument.main(new String[]{"a","b","c"});
2)反射調用main方法
String starClassName=”com.zsw.TestArgument”;
Method mainMethod =Class.forName(starClassName).getMethod("main", String[].class);
mainMethod.invoke(null, new Object[]{new String[]{"張111","222","333"}});
//mainMethod.invoke(null, (Object)new String[]{"張111","222","333"});
3)JDK1.5的語法,反射調用方法時:當傳遞來的是一個數組,就會自動解包,爲了防止數據出錯。
① 將數組在封裝到一個數組裏面,解包後就是原始數據了。
②將數組強制轉換成一個Object對象,編譯器就認爲其不是數組,就不會拆包了,以此欺騙編譯器。