自從Jdk1.5推出了反射,java從一種靜態(tài)語言變?yōu)橐环N動(dòng)態(tài)語言了??梢詣?dòng)態(tài)調(diào)用方法的具體方法、實(shí)現(xiàn)等等,一下高端大氣上檔次起來。
1、反射是什么
反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法和屬性;這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱為java語言的反射機(jī)制。
2、反射機(jī)制能做什么
- 在運(yùn)行時(shí)判斷任意一個(gè)對(duì)象所屬的類;
- 在運(yùn)行時(shí)構(gòu)造任意一個(gè)類的對(duì)象;
- 在運(yùn)行時(shí)判斷任意一個(gè)類所具有的成員變量和方法;
- 在運(yùn)行時(shí)調(diào)用任意一個(gè)對(duì)象的方法;
3、反射機(jī)制的相關(guān)API及使用
代碼參見com.critc.ReflectTest
/**
* Created by 孔垂云 on 2017/4/17.
* 通過一個(gè)對(duì)象獲得完整的包名和類名
*/
public class ReflectTest {
public static void main(String[] args) throws Exception {
//通過一個(gè)對(duì)象獲得完整的包名和類名
ReflectTest testReflect = new ReflectTest();
System.out.println(testReflect.getClass().getName());
// 結(jié)果 com.critc.ReflectTest
//實(shí)例化Class類對(duì)象
Class<?> class1 = null;
Class<?> class2 = null;
Class<?> class3 = null;
// 一般采用這種形式
class1 = Class.forName("com.critc.ReflectTest");
class2 = new ReflectTest().getClass();
class3 = ReflectTest.class;
System.out.println("類名稱 " + class1.getName());
System.out.println("類名稱 " + class2.getName());
System.out.println("類名稱 " + class3.getName());
//獲取某個(gè)類的全部屬性
Class<?> clazz = Class.forName("com.critc.vo.User1");
System.out.println("===============本類屬性===============");
// 取得本類的全部屬性
Field[] field = clazz.getDeclaredFields();
for (int i = 0; i < field.length; i++) {
// 權(quán)限修飾符
int mo = field[i].getModifiers();
String priv = Modifier.toString(mo);
// 屬性類型
Class<?> type = field[i].getType();
System.out.println(priv + " " + type.getName() + " " + field[i].getName() + ";");
}
//獲取某個(gè)類的全部方法
Class<?> clazz2 = Class.forName("com.critc.vo.User1");
Method method[] = clazz2.getMethods();
System.out.println("==========所有方法如下:=========");
for (int i = 0; i < method.length; ++i) {
Class<?> returnType = method[i].getReturnType();
Class<?> para[] = method[i].getParameterTypes();
int temp = method[i].getModifiers();
System.out.print(Modifier.toString(temp) + " ");
System.out.print(returnType.getName() + " ");
System.out.print(method[i].getName() + " ");
System.out.print("(");
for (int j = 0; j < para.length; ++j) {
System.out.print(para[j].getName() + " " + "arg" + j);
if (j < para.length - 1) {
System.out.print(",");
}
}
Class<?> exce[] = method[i].getExceptionTypes();
if (exce.length > 0) {
System.out.print(") throws ");
for (int k = 0; k < exce.length; ++k) {
System.out.print(exce[k].getName() + " ");
if (k < exce.length - 1) {
System.out.print(",");
}
}
} else {
System.out.print(")");
}
System.out.println();
}
System.out.println("==========調(diào)用類的方法===========");
//調(diào)用類的方法
Class<?> clazz3 = Class.forName("com.critc.vo.User1");
Method method3 = clazz3.getMethod("setId", int.class);
//method3.invoke(clazz.newInstance());//先調(diào)用new方法
method3.invoke(clazz3.newInstance(), 20);//調(diào)用set方法
User1 user1 = new User1("測(cè)試", 10, "123");
Class clazz4 = user1.getClass();
Method method4 = clazz4.getDeclaredMethod("getName");
String name = (String) method4.invoke(user1);//調(diào)用get方法
System.out.println(name);
}
}
應(yīng)用場(chǎng)景主要包括以下:
1、參數(shù)替換,比如一段文字里面的參數(shù)${id},${name}等,傳過來一個(gè)對(duì)象,就可以先用正則表達(dá)式獲取這些參數(shù),然后調(diào)用參數(shù)的get方法
2、動(dòng)態(tài)調(diào)用一些列的方法,比如兩個(gè)類都繼承一個(gè)接口,要根據(jù)參數(shù)來判斷調(diào)用哪個(gè)類的哪個(gè)方法,就可以動(dòng)態(tài)調(diào)用了。
3、spring里面的BeanFactory,最常用的,后面會(huì)單獨(dú)講