一医吊、初步認識反射###
使用反射,能夠快速地應用開發(fā)工具動態(tài)地查詢新添加類的能力宝磨。能夠分析類能力的程序稱為反射。反射機制的功能極其強大盅安,我們可以用它來:
- 在運行中分析類的能
- 在運行中查看對象唤锉,例如,編寫一個toString方法供所有類使用
- 實現(xiàn)通用的數(shù)組操作代碼
- 利用Method對象别瞭,這個對象很像C++中的函數(shù)指針
二窿祥、Class類###
在程序運行期間,Java運行時系統(tǒng)始終為所有的對象維護一個被稱為運行時的類型標識蝙寨。這個信息跟蹤著每個對象所屬的類晒衩。虛擬機利用運行時類型信息選擇相應的方法執(zhí)行。保存這些信息的類被稱為Class墙歪,我們有三種常見的方法獲取該類:
- Object類中的getClass()方法將會返回一個Class類型的實例
Date d = new Date();
Class c1 = d.getClass();
String name = c1.getName(); // name is set to "java.util.Date"
- 還可以調用靜態(tài)方法forName獲得類名對應的Class對象
String className = "java.util.Date";
Class c1 = Class.forName(className);
- 如果T是任意的Java類型听系,T.class將代表匹配的類對象。例如:
Class c1 = Date.class; // if you import java.util.*;
Class c2 = int.class;
Class c3 = Double[].class;
三虹菲、捕獲異常###
Class.forName方法會拋出一個已檢查異常靠胜,我們將可能拋出已檢查異常的一個或多個方法調用代碼放在try塊中,然后在catch子句中提供處理器代碼,下面是一個示例:
try{
String mame = ""; //get class name
Class c1 = Class.forName(name); //might throw exception
do something with c2
}catch (Exception e) {
e.printStackTrace();
}
}
當類名不存在的時候浪漠,則將跳過try塊中的剩余代碼陕习,程序直接進入catch子句。
java.lang.Class 1.0
static Class forName(String className)
//返回描述類名為className的Class對象址愿。
Object newInstance()
//返回這個類的一個新實例
四该镣、利用反射分析類的能力###
下面簡要地介紹一下反射機制最重要的內容--檢查類的結構
在java.long.reflect包中有三個類Field、Method和Constructor分別用來描述類的域必盖、方法和構造器拌牲。
這三個類都有一個叫做getName()
的方法,用來返回項目的名稱歌粥。具體每個類各自有什么方法塌忽,下面會具體闡述。
Modifier信息的獲取####
try{
//打印類名和父類名(if != Object) 我們給的測試name為java.util.Date
Class cl = Class.forName(name);
Class supercl = cl.getSuperclass();
System.out.println(cl.getModifiers());
String modifiers = Modifier.toString(cl.getModifiers());
if(modifiers.length()>0) System.out.println(modifiers + " ");
System.out.println("class " + name);
if(supercl!=null&&supercl!=Object.class) //Date的父類為Object
System.out.println("extends"+supercl.getName());
}catch (Exception e) {
e.printStackTrace();
}
運行結果:
1
public
class java.util.Date
PS:class類的getModifiers()
方法返回的是一個整形數(shù)值失驶,對應相應的權限土居,通過Modifier.toString(cl.getModifiers())
可以將對應的修飾符打印出來
Constructor信息的獲取#####
public static void printConstructors(Class cl){ //打印一個Class的所有構造方法
Constructor[] constructor = cl.getDeclaredConstructors();
for(Constructor c : constructor){
String name = c.getName();
System.out.print(" ");
String modifiers = Modifier.toString(c.getModifiers());
if(modifiers.length()>0) System.out.print(modifiers+" ");
System.out.print(name + "(");
//打印參數(shù)的類型
Class[] paramTypes = c.getParameterTypes();
for(int j = 0 ; j < paramTypes.length; j++){
if(j>0) System.out.print(",");
System.out.print(paramTypes[j].getName());
}
System.out.println(");");
}
}
運行結果:
----測試printConstructors()方法
public java.util.Date(java.lang.String);
public java.util.Date(int,int,int,int,int,int);
public java.util.Date(int,int,int,int,int);
public java.util.Date();
public java.util.Date(long);
public java.util.Date(int,int,int);
Method信息的獲取#####
public static void printMethods(Class cl){ //打印一個Class的所有方法
Method[] methods = cl.getDeclaredMethods();
for(Method m : methods){
Class retType = m.getReturnType();
String name = m.getName();
System.out.println(" ");
//打印訪問權限,返回值類型和方法名
String modifiers = Modifier.toString(m.getModifiers());
if(modifiers.length()>0) System.out.print(modifiers + " ");
System.out.print(retType.getName() + " " + name + "(");
//打印參數(shù)的類型
Class[] paramTypes = m.getParameterTypes();
for(int j = 0 ; j < paramTypes.length ; j++){
if(j > 0) System.out.print(",");
System.out.print(paramTypes[j].getName());
}
System.out.println(");");
}
}
運行結果:(這個方法有點多嬉探,只打印其中的一部分)
----測試printMethods()方法
public boolean equals(java.lang.Object);
public java.lang.String toString();
public int hashCode();
public java.lang.Object clone();
public volatile int compareTo(java.lang.Object);
public int compareTo(java.util.Date);
private void readObject(java.io.ObjectInputStream);
private void writeObject(java.io.ObjectOutputStream);
Field信息的獲取#####
public static void printFields(Class cl){ //打印一個Class中的所有fields
Field[] fields = cl.getFields();
for(Field f : fields){
Class type = f.getType();
String name = f.getName();
System.out.print(" ");
String modifiers = Modifier.toString(f.getModifiers());
if(modifiers.length() > 0) System.out.print(modifiers + " ");
System.out.println(type.getName() + " "+name+ ";");
}
}
//由于我們輸入的Date類中沒有特殊的字段擦耀,結果不予展示了
PS:Class類中的getFields()
、getMethods()
和getConstructors()
方法將分別返回類提供的public域涩堤、方法和構造器數(shù)組眷蜓,其中包括超類的公有成員。Class類的getDeclareFields()
胎围、getDeclareMethods()
和getDeclaredConstructors()
方法將分別返回類中聲明的全部域吁系、方法和構造器,其中包括私有和受保護成員白魂,但不包括超類的成員汽纤。
上述三個類中獲取不同參數(shù)的方法返回值的類型是Class,Method.getReturnType()
福荸、Method.getParameterTypes()
以及Constructor.getParameterTypes()
等方法等返回值都是Class[]類型蕴坪。