Java反射

Class類的使用

  • 所有類都是Class類的對象,這種對象有三種表示方式
// c1/c2/c3是Foo的類類型
// 一個類的類類型只有一個,即 c1==c2==c3
Class c1 = Foo.class;
Class c2 = foo.getClass();
Class c3 = Class.forName("Foo");
  • 可以通過類類型創(chuàng)建對象
Foo foo = (Foo)c1.newInstance(); // Foo需要有無參構(gòu)造方法
  • 基本數(shù)據(jù)類型、void關(guān)鍵字都有類類型

方法的反射

  • Method類:一個方法就是一個Method對象。
  • 根據(jù)類類型獲取方法
 // 獲取public方法,包括父類方法
Method[] methods = c.getMethods();
// 獲取當(dāng)前類聲明的方法,不論訪問權(quán)限
Method[] methods = c.getDeclaredMethods();
  • 根據(jù)方法獲取返回值類類型
Class returnClassType = method.getReturnType();
  • 獲取方法名稱
String methodName = method.getName();
  • 根據(jù)方法獲取方法參數(shù)類類型數(shù)據(jù)
Class[] paramClassTypes = method.getParameterTypes();
  • 獲取某一方法
// 獲取帶兩個int類型參數(shù)的,名字為print的方法
Method method = c.getMethod("print",int.class,int.class) 
  • 方法的操作
    格式:method.invoke(obj,params[])
//調(diào)用a對象的print方法,傳入兩個參數(shù)
method.invoke(a,10,20);
//和直接調(diào)用方法效果一樣
a.print(10,20);

成員變量的反射

  • Field類:一個成員變量就是一個Field對象。
  • 根據(jù)類類型獲取成員變量
 // 獲取public成員變量,包括父類成員變量
Field[] fields = c.getFields();
// 獲取當(dāng)前類聲明的成員變量,不論訪問權(quán)限
Field[] fields = c.getDeclaredFields();
  • 例子
// 修改字符串的內(nèi)容而不修改地址
        //獲取之前的值
        String s = new String("abc");
        System.out.println(s);
        String s1 = s;

        //利用反射屬性修改值
        Field field = null;
        try {
            field = s.getClass().getDeclaredField("value");

            field.setAccessible(true);
            field.set(s,"abcd".toCharArray());
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        //修改后的值
        System.out.println(s);
        System.out.println(s1 == s);
  • 獲取成員變量的類類型
Class fieldClassType = field.getType();
  • 獲取成員變量名稱
String fieldName = field.getName();

構(gòu)造函數(shù)的反射

  • Constructor類:一個構(gòu)造函數(shù)就是一個Constructor對象。
  • 根據(jù)類類型獲取構(gòu)造函數(shù)
 // 獲取public構(gòu)造函數(shù),包括父類構(gòu)造函數(shù)
Constructor[] constructors = c.getConstructors();
// 獲取當(dāng)前類聲明的構(gòu)造函數(shù),不論訪問權(quán)限
//建議使用,因為構(gòu)造方法都需要自己聲明
Constructor[] constructors = c.getDeclaredConstructors();
  • 獲取構(gòu)造函數(shù)名稱
String methodName = constructor.getName();
  • 根據(jù)方法獲取構(gòu)造函數(shù)參數(shù)類類型數(shù)據(jù)
Class[] paramClassTypes = constructor.getParameterTypes();

Java類加載機制

  • 靜態(tài)加載類:編譯時加載類
    new對象是靜態(tài)加載類,在編譯時加載可能用到的類
  • 動態(tài)加載類:運行時加載類
    Class.forName得到類類型,通過類類型創(chuàng)建對象是動態(tài)加載

需求實例:程序中如果是World調(diào)用World的啟動方法,如果是Excel調(diào)用Excel的啟動方法,等等。
思路:如果直接在這個類中使用World、Excel等類,當(dāng)某一個可能不會用到的類不存在時會報錯,所以需要動態(tài)加載

1.抽象出公共功能:

public interface OfficeAble {
    void start();
}

2.實際類擁有功能:

public class World implements OfficeAble {
    @Override
    public void start() {
        System.out.println("World start...");
    }
}
public class Excel implements OfficeAble {
    @Override
    public void start() {
        System.out.println("Excel start...");
    }
}

3.實際使用:

public class OfficeTest {
    public static void main(String[] args) {
        try {
//            Class c = Class.forName("com.zp.zptest.reflect.World");
            Class c = Class.forName("com.zp.zptest.reflect.Excel");
            OfficeAble officeAble = (OfficeAble) c.newInstance();
            officeAble.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

用反射認(rèn)識泛型的本質(zhì)

  • 反射是編譯后的操作
  • 編譯后的集合是去泛型化的
  • Java泛型是為了防止錯誤輸入,只在編譯時生效
  1. 反射是去泛型化的:
        ArrayList list1 = new ArrayList();
        ArrayList<String> list2 = new ArrayList<String>();
        Class c1 = list1.getClass();
        Class c2 = list2.getClass();
        System.out.println(c1 == c2); // 結(jié)果為true
  1. 使用反射給c2添加整型元素:
        list2.add("hello");
        Method method = c2.getMethod("add",Object.class);
        method.invoke(list2,10);
        System.out.println(list2); // [hello,10]
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容