一,
反射基本概念:
反射機制是在【運行狀態】中可以獲取一個類的所有屬性,和方法(包括構造器)並且能夠調用其任意一個方法和屬性。
反射常用功能大致如下:
- 在運行期間獲取任意一個對象的所屬類
- 在運行期間構造任意一個類的對象
- 在運行期間獲取一個類所具有的所有公共,私有的成員變量和方法
- 在運行期間可以調用某個類的任意一個方法,構造方法
提示:我們所知道的有點高端的動態代理的底層支持其實就是反射
二,
獲取類的三種方式:
代碼片段中分割線表示另一個文件,另外代碼片段接近僞代碼沒有什麼實際業務做鋪墊。
Order order = new Order();
/**
* Class.forName() 根據全類名構造一個Class
* 對象通過調用 getClass() 方法獲取其Class
* .class 是一個特殊語法,獲取當前類在JVM生成的Class
*/
public Order(){
Syste.out.println("無參構造");
}
private Order(String name){
System.out.println(name);
}
Class classThree = Class.forName("cn.entity.Order");
Class classOne = order.getClass();
Class classTwo = Order.class();
======================================================================================
package cn.entity
public class Order implements Service,IService{
private String name;
private int age;
private char gender;
public void setName(String name){ this.name = name; }
public String getName(){ return name; }
public void setAge(int age){ this.age = age; }
public int getAge(){ return age; }
public void setGender(char gender){ this.gender = gender; }
public char getGender(){ return gender; }
@Override
public void orderGeneral(){
}
@Override
public void orderManager(){
}
}
======================================================================================
public interface Service{
void orderGeneral();
}
=======================================================================================
public interface IService{
void orderManager();
}
獲取方法,構造方法,接口,父類:
/**
* 獲取所有的公共方法(當前類、父類以及接口中所有公共修飾的方法)
*/
Method[] methods = classOne.getMethos();
for(Method method:methods){
System.out.println(method);
}
=========================================================================================
/**
* 獲取所有構造方法
*/
Constructor<?>[] constructors = classOne.getConstructors();
for(Constructor constructor:constructors){
System.out.println(constructor);
}
=========================================================================================
/**
* 獲取所有接口
*/
Class<?>[] interfaces = classOne.getInterface();
for(Class<?> inteface:interfaces){
System.out.println(interfaces);
}
=========================================================================================
/**
* 獲取所有父類
*/
Class<?> superClass = classOne.getSuperClass();
System.out.println(superClass);
=========================================================================================
/**
* 獲取所有公共屬性
*/
Field[] fields = classOne.getFields();
for(Field field:fields){
System.out.println(field);
}
=========================================================================================
/**
* 獲取當前類所有方法
*/
Method[] methods = classOne.getDeclaredMethods();
for(Method method:methods){
System.out.println(method);
}
=========================================================================================
/**
* 獲取當前類所有屬性
*/
Field[] fields = classOne.getDeclaredFields();
for(Field field:Fileds){
System.out.println(field);
}
獲取並操作對象:
/**
* 獲取 class 對象並強轉,調用該對象的方法
*/
Order order = (Order)classOne.newIstance();
order.setName("阿狗");
order.setAge("10");
order.setGender('男');
=========================================================================================
/**
* 操作某個屬性
* 下面代碼中 nameField.setAccessible(true) [默認值爲 false] 作用是:
* 忽略 name 屬性的訪問修飾符
*/
Order order = (Order)classOne.newInstance();
Field nameField = classOne.getDeclaredField("name");
nameField.setAccessible(true);
nameField.set(order,"阿狗");
System.out.println(order.getName());
=========================================================================================
/**
* 調用無參方法,DeclaerdMthod 參數列表:1.方法名(String) 2.參數類型(class)
* 方法名參數將方法名的字符串傳入,參數類型 由於是無參方法傳入 null 即可
*/
Order order = (Order)classOne.newInstance();
Method method = classOne.getDeclaredMethod("getName",null);
method.invoke(order,null);
=========================================================================================
/**
* 調用有參方法,DeclaredMthod 參數列表: 1.方法名(String) 2.參數類型(class);
* 方法名參數將方法名的字符串傳入,參數類型需要 類型class;比如: int.class String.class
*/
Order order = (Order)classOne.newInstance();
Method method = classOne.getDeclaredMethod("setName",String.class);
method.invoke(order,"阿狗");
=========================================================================================
/**
* 有參構造 和 無參構造
* getDeclaredConstructor() 獲取所有的構造函數 、
* getConstructor() 獲取公共構造函數
*/
Constructor constructor = classOne.getDelcaredConstructor(String.class); //有參構造
constructor.setAccessible(true);
Order order = (Order)constructor.newInstance("阿狗");
Constructro constructor = classOne.getContructor(); //無參構造
Order order = (Order)constructor.newInstance();
說明:上面代碼獲取有參構造函數使用了getDecalerdConstructor(),因爲有參構造函數是一個私有的;
獲取無參構造使用了getConstructor(),因爲無參構造函數是公共的。
注意:上面代碼中setAccessible()函數只是作爲一個瞭解,實際開發中不建議使用。
文章是我自己個人的一點總結,所以本文會持續更細;讀者如發現有錯誤或者不合理的地方歡迎指出