一、開場白
想必學java的小夥伴對反射都不陌生吧,反射在我們的開發中實用性很大,你用好了反射,你的代碼整潔、代碼性能、代碼優化等都會大幅度的提高,所以不會用反射的小夥伴要多多學習了;下面我給大家說說反射的實用性。
二、概念以及作用
1. 概念:
Java的反射(reflection)機制是指在程序的運行狀態中,可以構造任意一個類的對象,可以瞭解任意一個對象所屬的類,可以瞭解任意一個類的成員變量和方法,可以調用任意一個對象的屬性和方法。這種動態獲取程序信息以及動態調用對象的功能稱爲Java語言的反射機制;
2. 運用:
首先大家要明白一點,咱們寫的代碼是存儲在後綴名是 .java的文件裏的,但是它會被編譯,最終真正去執行的是編譯後的 .class文件。Java是面向對象的語言,一切皆對象,所以java認爲 這些編譯後的 class文件,這種事物也是一種對象,它也給抽象成了一種類,這個類就是Class,大家可以去AIP裏看一下這個類;
https://tool.oschina.net/apidocs/apidoc?api=jdk-zh
<1> 通過反射創建對象
我們下面來舉一個例子,下面這個例子就是創建了一個class對象
Class user= Class.forName("com.test.User");
但是我們想要new一個對象咋辦?下面就來通過反射new一個無參對象;
User user= Class.forName("com.test.User").newInstance();
這樣我們就把對象new好了,可以使用user中的方法了,但是我要構造有參的咋辦,不要急下面我們來構造一個;
Class user= Class.forName("com.test.User");
Constructor c=clazz.getConstructor(String.class,int.class);//獲取有參構造
User user=(User ) c.newInstance("sanmao",12); //通過有參構造創建對象
好了我們通過反射構造對象就到這了。
<2> 通過反射機制來獲取屬性的類型
我們下面來舉一個例子,獲取單個屬性的返回值
Field field = User.class.getDeclaredField("name");
System.out.println(field.getName()); //獲取屬性name的
System.out.println(field.getType());//獲取屬性類型 class的
下面是獲取所有屬性的返回值
Field[] fields = User.class.getDeclaredFields();
System.out.println(field.getName()); //獲取屬性name的
System.out.println(field.getType());//獲取屬性類型 class的
還有其他返回值,大家可以打斷點研究研究,我就寫這兩個值。
<3> 通過反射來set,get值
https://tool.oschina.net/apidocs/apidoc?api=jdk-zh
我們下面來舉一個例子,獲取單個屬性並且set值
// 獲取bean的某個屬性的描述符
PropertyDescriptor propDesc = new PropertyDescriptor(name, User.class);
// 獲得用於寫入屬性值的方法
Method methodSetName = propDesc.getWriteMethod();
// 寫入屬性值
methodSetName.invoke(user, "wong");
我們下面來舉一個例子,獲取單個屬性並且get值
// 獲取Bean的某個屬性的描述符
PropertyDescriptor proDescriptor = new PropertyDescriptor(name, User.class);
// 獲得用於讀取屬性值的方法
Method methodGetrName = proDescriptor.getReadMethod();
// 讀取屬性值
Object objName = methodGetName.invoke(user);
我們下面來舉一個例子,獲取所有屬性並且set、get值
BeanInfo beanInfo = Introspector.getBeanInfo(user.getClass(), Object.class);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor p : propertyDescriptors) {
//獲得屬性名稱
String name = p.getName();
Map<String, Object> map = new HashMap<>();
//調用該屬性名稱對應的getter方法
Object obj = new PropertyDescriptor(p.getName(), User.class).getReadMethod().invoke(user);
//調用該屬性名稱對應的setter方法
new PropertyDescriptor(p.getName(), User.class).getWriteMethod().invoke(user, obj);
}
上面所說的幾個反射都是最常用的,大家如果遇到其他的問題,可以來聯繫我,請關注下面的公衆號留言。