最近想對(duì)Retrofit做一次源碼分析瞳腌,里面涉及到很多諸如反射和動(dòng)態(tài)代理等一些Java特性,先回顧一下
- 反射機(jī)制概述
- Class對(duì)象的機(jī)制與實(shí)現(xiàn)
- Field對(duì)象的機(jī)制與實(shí)現(xiàn)
- Method對(duì)象的機(jī)制與實(shí)現(xiàn)
反射機(jī)制背景概述
Reflection是java被視為動(dòng)態(tài)或準(zhǔn)動(dòng)態(tài)語(yǔ)言的一個(gè)關(guān)鍵性質(zhì),反射機(jī)制指的是程序在運(yùn)行時(shí)能夠獲取人和類(lèi)的內(nèi)部所有信息
- 反射機(jī)制實(shí)現(xiàn)功能概述
- 只要給定類(lèi)的全名,即刻通過(guò)反射獲取類(lèi)的所有信息
- 反射可以在程序運(yùn)行時(shí)獲取任意一個(gè)對(duì)象所屬的類(lèi)對(duì)象
- 在運(yùn)行時(shí)可以獲取到類(lèi)中所有屬性對(duì)象,并對(duì)其操作鞭光,包括私有屬性
- 在運(yùn)行時(shí)可以獲取到類(lèi)中,弗雷中所有方法泞遗,并調(diào)用
- 目前主流的應(yīng)用框架如Struts2惰许,Hibernate,Spring史辙,SpringMVC等框架的核心都是利用java的反射機(jī)制來(lái)實(shí)現(xiàn)的
Class對(duì)象的機(jī)制與實(shí)現(xiàn)
class其實(shí)就是類(lèi)的類(lèi)型,字符串類(lèi)型是String汹买,整形類(lèi)型就是Integer佩伤,String和Integer類(lèi)型就是Class
getName() 獲取類(lèi)中完整名稱(chēng)
getDeclaredFields()取類(lèi)中所有屬性
getDeclaredmethods() 獲取類(lèi)中所有的方法
getConstructor() 獲取類(lèi)構(gòu)造方法
getInstance()實(shí)例化對(duì)象
class對(duì)象操作
public class ClazzTest {
public static void main(String[] args){
Class demo1= null;
Class demo2= null;
Class demo3= null;
//第一種方式
try {
demo1 =Class.forName("com.gunther.reflection.main.Book");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("第一種:"+demo1);
//第二種
Book book = new Book();
Object ob = book;
System.out.println("第二種:"+ob.getClass());
//第三種
demo3=Book.class;
System.out.println("第三種:"+demo3);
try {
Book book1 = (Book) demo3.newInstance();
System.out.println("實(shí)例化后的類(lèi)對(duì)象:"+book1);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
public class Book {
private int id;
private String name;
private String type;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Field對(duì)象的機(jī)制與實(shí)現(xiàn)
java.lang.reflect.Field類(lèi),是勇于標(biāo)識(shí)類(lèi)中卦睹,接口中屬性對(duì)象的類(lèi),可以操作類(lèi)中私有畦戒,以及共有等全部屬性和屬性的信息
Field對(duì)象的常用方法介紹
- getName() 獲取屬性名稱(chēng)
- getType()獲取屬性類(lèi)型
- get(Object obj)獲取obj對(duì)象中這個(gè)屬性的值
- set(Object obj,Object value)向obj對(duì)象中這個(gè)屬性賦值value
- setAccessible(true) 啟用/禁止訪問(wèn)控制權(quán)限
field對(duì)象操作
public class FieldTest {
public static void main(String[] args) {
Book book = new Book();
book.setId(1);
book.setName("無(wú)線(xiàn)智能水壓表");
book.setType("消火栓");
FieldTest fieldTest = new FieldTest();
fieldTest.show(Book.class);
}
//該方法用于使用傳遞過(guò)來(lái)的Class對(duì)象獲取類(lèi)中的屬性
public void show(Class clazz) {
Field[] fi = clazz.getDeclaredFields();
//可以將私有屬性也獲取,getField智能獲取公有屬性
for (Field ff : fi) {
System.out.println(ff.getName());
System.out.println(ff.getType());
}
}
//該方法勇于使用傳遞過(guò)來(lái)的實(shí)體類(lèi)對(duì)象结序,獲取屬性以及屬性的值
public void show(Object ob) {
Class clazz = ob.getClass();
Field[] fi = clazz.getDeclaredFields();
try {
for (Field ff : fi) {
ff.setAccessible(true);//設(shè)置啟用
System.out.println(ff.getName() + "值" + ff.get(ob));
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
Method對(duì)象的機(jī)制與實(shí)現(xiàn)
java.lang.relect.Method類(lèi)是勇于標(biāo)識(shí)類(lèi)中障斋,接口中方法對(duì)象的類(lèi),可以操作類(lèi)中私有,以及共有等全部方法
Method對(duì)象常用方法介紹
getName 獲取方法名稱(chēng)
getReturnType 獲取方法返回值類(lèi)型
invoke(Object obj,Object...args)利用obj對(duì)象調(diào)用該方法
getParameterTypes() 獲取方法所有參數(shù)類(lèi)型徐鹤,按照順序返回Class數(shù)組
getDeclaredAnnotations()獲取方法的全部注解
method對(duì)象操作
public class MethodTest {
public static void main(String[] args) {
Book book = new Book();
book.setId(1);
book.setName("無(wú)線(xiàn)智能水壓表");
book.setType("消火栓");
MethodTest methodTest = new MethodTest();
methodTest.show(book);
methodTest.showUse(book);
System.out.println(book.getName());
}
//該方法用于獲取對(duì)象所有方法名稱(chēng)垃环,返回值類(lèi)型,以及參數(shù)信息
public void show(Object ob) {
Class<?> clazz = ob.getClass();
Method[] me = clazz.getDeclaredMethods();
for (Method mm : me) {
System.out.println("方法名稱(chēng):" + mm.getName());
System.out.println("方法修飾符:" + mm.getModifiers());
System.out.println("方法返回值類(lèi)型:" + mm.getReturnType());
Class[] preType = mm.getParameterTypes();
System.out.println("方法參數(shù)列表:");
for (Class cl : preType) {
System.out.println(cl.getName());
}
}
}
//該方法用于獲取對(duì)象,獲取其中方法并調(diào)用
public void showUse(Object ob) {
Class<?> clazz = ob.getClass();
try {
Method me = clazz.getMethod("getName", null);
me.invoke(ob,new Object[0]);
Method me1 = clazz.getMethod("setName", String.class);
me.invoke(ob,"test");
} catch (Exception e) {
e.printStackTrace();
}
}
}