Java 反射詳解,快速瞭解如何使用

一,

反射基本概念:

反射機制是在【運行狀態】中可以獲取一個類的所有屬性,和方法(包括構造器)並且能夠調用其任意一個方法和屬性。

 

反射常用功能大致如下:

  • 在運行期間獲取任意一個對象的所屬類
  • 在運行期間構造任意一個類的對象
  • 在運行期間獲取一個類所具有的所有公共,私有的成員變量和方法
  • 在運行期間可以調用某個類的任意一個方法,構造方法

 提示:我們所知道的有點高端的動態代理的底層支持其實就是反射

 

二,

獲取類的三種方式:

代碼片段中分割線表示另一個文件,另外代碼片段接近僞代碼沒有什麼實際業務做鋪墊。

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()函數只是作爲一個瞭解,實際開發中不建議使用。

 

文章是我自己個人的一點總結,所以本文會持續更細;讀者如發現有錯誤或者不合理的地方歡迎指出

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章