NO IMAGE

我們先來看反射提供的功能:

反射機制提供功能:載入執行時確定資料型別,解析類結構,獲取內部資訊

操作該型別或例項,訪問屬性,呼叫方法,建立新物件

java反射是誰來提供呢?

Class物件提供,但是首先需要通過JVM獲取物件,建立Class物件

建立Class物件有三種方式:

使用Class類的forName()靜態方法如:Class.forName(java.lang.reflect.Field)

呼叫類的class屬性獲取對應的Class物件,

呼叫某個物件的getClass()方法

獲取Class物件,就可以得到物件的真實資訊

如:物件的建構函式,屬性,方法,註解,介面,父類,註解(必須是具有原始碼,否則註解不能查詢到)等

如:

Constructor<?>getconstructors()返回class物件標識的所有public 構造器
Method[] getMethods()
FieldgetField(String name)
Annotation[]getAnnotations()

以上方法是有多過載的,可根據引數型別獲取不同如 class.getMethod(“info”,String.class) 

反射能做什麼?

以上是通過反射獲取物件,取得物件的屬性方法

同時反射還可以生成物件以及操作物件的方法,形成動態代理的基礎,ORM的基礎

建立物件方式

使用Class物件newIntance()建立class物件例項,但必須有預設構造器

或使用class物件指定的構造器,再呼叫newInstance方法,可以建立指定例項

 事例

獲取某個物件,並建立該物件呼叫該物件方法

1 POJO類

public class User {
private String userName;
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public User(){
}
public User(String username){
this.userName=username;
}

2 呼叫類與例項

public static void main(String[] args) throws SecurityException,
NoSuchFieldException, InstantiationException, IllegalAccessException,
NoSuchMethodException, ClassNotFoundException {
getProperty(User.class);//呼叫
}
public static void getProperty(Class<?> entityClass) throws SecurityException,
NoSuchFieldException, InstantiationException, IllegalAccessException,
NoSuchMethodException, ClassNotFoundException {
//-----start----反射獲取物件---------
String cName = entityClass.getName();
// 從類的名字中解析出類名
String userName = cName.substring(cName.lastIndexOf(".")   1, cName.length());
System.out.println("實體名稱為:"  userName);
// 獲取物件的所有屬性
Field[] fields = entityClass.getDeclaredFields();
// 獲取物件的所有方法
Method[] methods = entityClass.getDeclaredMethods();
List<String> listfeld = new ArrayList<>();
for (Field field : fields) {
System.out.println("屬性名稱有:"   field.getName());
}
for (Method method : methods) {
System.out.println("方法名稱有:"   method.getName());
}
//-------反射獲取物件-end-------- 
//反射建立物件,呼叫物件方法-------start--------
User userfroname = (User)	Class.forName(cName).newInstance();        //獲取Class物件方式1 :通過字串
User userClass = (User) entityClass.newInstance();                      //獲取Class物件方式2: 通過Class型別
userClass.setUserName("我的大名是:任秋明---通過class名稱建立物件");
userfroname.setUserName("我的大名是:任秋明--Class型別建立物件");
System.out.println(userClass.getUserName());
System.out.println(userfroname.getUserName());
//反射建立物件,呼叫物件方法-------end--------
}

3 測試結果

實體名稱為:User
屬性名稱有:userName
屬性名稱有:password
方法名稱有:getUserName
方法名稱有:setUserName
方法名稱有:setPassword
方法名稱有:getPassword
我的大名是:任秋明—通過class名稱建立物件
我的大名是:任秋明–Class型別建立物件

小結:

 總的來說,java反射機制可以解決一些不靈活的程式,IOC的依賴注入,動態代理,動過名稱反射呼叫類的方法。但與此同時反射同時也帶來的效率上的問題,凡事都有兩面性,要靈活難免犧牲效率。