1. 程式人生 > >黑馬程式設計師----Java基礎之反射

黑馬程式設計師----Java基礎之反射

------- <a href="http://www.itheima.com" target="blank">android培訓</a>、<a href="http://www.itheima.com" target="blank">java培訓</a>、期待與您交流! ---------

反射:

反射的基石:::Class類

Java程式的各個Java類屬於同一類事物,描述這類事物的java類名就是Class;Class類代表Java類,它的各個例項物件分別對應各個類在記憶體中的位元組碼.

一個類被類載入器載入到記憶體中,佔用一片記憶體空間,這個空間裡面的內容就是類的位元組碼,不同的類的位元組碼是不同的,所以他們在記憶體中的內容志不同的,這一個個的空間可分別用一個個的物件來表示,這些物件顯然具有相同的型別

Java類用於描述一類事物的共性,該類事物有什麼屬性,沒有什麼什麼屬性,至於這個屬性的值是什麼,則是由這個類的例項物件來確定的,不同的Class,要注意與小寫class關鍵字的區別.Class類描述了那些方面的資訊?類的名字,類的訪問屬性,類所屬的包名,欄位名稱的列表等

得到各個位元組碼對應的例項物件的三種方式(Class 型別)

類名.class,例如:System.class

物件.getClass(),例如: new Date().getClass();

Class.forName("類名"),例如,Class.forName("java.util.Date");

物件名.isPrimitive();//判斷該物件是否是原始資料型別

舉例說明:

String  str = "abc";

Class cl1 = str.getClass();

Class cl2 = String.class;

Class ci2 = Class.forName("java.lang.String");

cl1==cl2==cl3;

判斷是否為陣列的原始型別Class.isArray();

int.class==Integer.TYPE;

總之,只要是在源程式中出現的型別,都有各自的Class例項物件

反射:就是把Java類中的各種成分對映成相應的Java類,一個java類中用一個Class類的物件來表示,一個類中的組成部分:成員變數,方法,建構函式,包等等資訊也用一個個的java類來表示,就像汽車是一個類,汽車中的發動機,變速箱等等也是一個個的類.表示Java類的Class顯然要提供一系列的方法來獲得其中

的變數,方法,構造方法,修飾符,包等資訊,這些資訊就是用相應類的例項物件來表示,它們是Field, Method, Constructor,Package等等

一個類中的每個成員都可以用相應的反射API類的一個例項物件來表示,通過呼叫Class類的方法可以得到這些例項物件.

Constructor類

Constructor類代表某個類中的一個構造方法

得到某個類所有的構造方法:

例子:Constructor[]  constructor = Class.forName("java.lang.String").getConstructors();

得到某一個構造方法:

例子:Constructor  constructor = Class.forName("java.lang.String").getConstructors(StringBuilder.class);

建立例項物件:

通常方式;String str = new String(new StringBuffer("abc"));

反射方式:String str = (String)constructor.newInstance(new StringBuffer("abc"));

用構造方法建立例項物件:

Constructor constructor1 = String.class.getConstructor(StringBuffer.class);

String str1 = (String)constructor1.newInstance(new StringBuffer("abc"));

char ch = str1.charAt(2);

System.out.println("ch="+ch);//結果為ch=c;

Class.newInstance()方法:直接建立空引數的構造方法(省略中間步驟,獲取構造方法類)

Field類:

Field類代表某個類中的一個成員變數

演示用eclips自動生成java類的構造方法



Method類

它代表某個類中的一個成員方法

得到類中某一個方法

例子:Method method= Class.forName("java.lang.String").getMethod("charAt",int.class)(方法名(字串),傳入的引數的位元組碼)

反射方式:System.out.println(method.invoke(Object obj , 1));

呼叫方法:

通常方式:System.out.println(str.charAt(1));

如果傳遞給Method物件的invoke方法的第一個引數為null,說明該Method物件對應的是一個靜態方法:

用反射方式執行某個類中的main方法;

目標:寫一個程式,這個程式那個根據使用者提供的類名,去執行該類中的main方法


陣列的反射

具有相同維數和元素型別的陣列屬於同一型別,即具有相同的Class例項物件.

代表陣列的Class例項物件getSuperClass()方法返回的父類的Object類對應的Class

基本型別的一維陣列可以被當作Object型別使用,不能當作Object[]型別使用;非基本型別的一維陣列,既可以當作Object[]型別使用,又可以當作Object型別使用.

Arrays.asList()方法處理int[]和String[]時的差異,Arrays工具類用於完成對陣列的反射操作

int[] a1= new int[3];

int[] a2 = new int[4];

int[][] a3 = new int[2][3];

String[] a4 = new String[3];

System.out,println(a1.getClass() == a2.getClass());//結果為true

System.out,println(a1.getClass() == a4.getClass());//結果為false

System.out,println(a1.getClass() == a3.getClass());//結果為false

System.out,println(a1.getClass().getSuperclass().getName());//結果為java.lang.Object

System.out,println(a4.getClass().getSuperclass().getName());//結果為java.lang.Object

基本資料型別的陣列不能轉換為Object的陣列

Object  obj1 = a1;//結果為true

Object  obj2 = a4;//結果為true

Object[]  obj3 = a1;//結果為false

Object[]  obj4 = a4;//結果為true

Object[]  obj15= a3;//結果為true

用反射的思想列印基本資料型別的元素

public static void run(Object obj)

{

Class clazz = obj.getClass();

if(clazz.isArray())

{

int len = Array.getLength(obj);

for(int x=0; x<len; x++)

{

System.out.println(Array.get(obj), x);

}

}

else

System.out.println(obj);

}

反射的作用:實現框架功能

框架與框架要解決的核心問題

我做房子賣給使用者,由使用者自己安裝門窗和空調,我做的房子就是框架,使用者需要使用我的框架,把門窗插入進我提供的框架中,框架與工具類有區別,工具類被使用者的類呼叫,而框架則是呼叫使用者提供的類:

框架要解決的核心問題

我在寫框架的時候,,我怎樣保證我寫的框架程式怎樣能呼叫到你以後寫的類呢?

因為在寫程式是無法知道要被呼叫的類名,所以,在程式中無法直接new某個類的例項物件了,而要用到反射方式來做