Java增強_反射的總結

一、反射概述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對象,編譯器就認爲其不是數組,就不會拆包了,以此欺騙編譯器。


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