Java獲取類或接口上的泛型類型T方法

前言

實際開發中,泛型使用到處可見。有時候定義接口時,經常使用泛型,而不是指定具體對象,使用泛型的好處很多,特別是代碼複用方面。要獲取類或接口上的泛型類型Class<?>,然後對這個類型進行數據處理,至於怎麼處理,還要看實際的應用場景。本篇講述如何獲取類或接口的泛型類型(參數化類型ParameterizedType)。

實例

1.定義泛型接口


public interface Response<T> {
    void onSuccess(T data);
}

2.定義泛型類

public static class BaseResponse<T> {
 }

3.定義測試類和測試方法
測試類

public static class SubResponse extends BaseResponse<Person> {

}

public static class Person {
    public String name;
}

測試方法

private static void test(SubResponse subResponse) {
        Class<?> clz = getClassT(subResponse, 0);
        System.out.println(clz.getSimpleName());
    }

    private static void test(Response a) {
        Class<?> clz = getInterfaceT(a, 0);
        System.out.println(clz.getSimpleName());
    }

4.調用

test(new Response<Person>() {
    @Override
    public void onSuccess(Person data) {

    }
});

test(new Response<List<Person>>() {
    @Override
    public void onSuccess(List<Person> data) {

    }
});
test(new SubResponse());

5.輸出結果
上面輸出都是Person
這個clz 就是person的Class,有了這個Class,可以做你想做的事情,比如:根據Class實例化對象、或者結合Class把json字符串和xml字符串轉化成具體的bean,然後再返回調用處。

獲取類或接口上的泛型類型T完整代碼

/**
     * 獲取接口上的泛型T
     *
     * @param o     接口
     * @param index 泛型索引
     */
    public static Class<?> getInterfaceT(Object o, int index) {
        Type[] types = o.getClass().getGenericInterfaces();
        ParameterizedType parameterizedType = (ParameterizedType) types[index];
        Type type = parameterizedType.getActualTypeArguments()[index];
        return checkType(type, index);

    }


    /**
     * 獲取類上的泛型T
     *
     * @param o     接口
     * @param index 泛型索引
     */
    public static Class<?> getClassT(Object o, int index) {
        Type type = o.getClass().getGenericSuperclass();
        if (type instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) type;
            Type actType = parameterizedType.getActualTypeArguments()[index];
            return checkType(actType, index);
        } else {
            String className = type == null ? "null" : type.getClass().getName();
           throw new IllegalArgumentException("Expected a Class, ParameterizedType"
                    + ", but <" + type + "> is of type " + className);
        }
    }

    private static Class<?> checkType(Type type, int index) {
        if (type instanceof Class<?>) {
            return (Class<?>) type;
        } else if (type instanceof ParameterizedType) {
            ParameterizedType pt = (ParameterizedType) type;
            Type t = pt.getActualTypeArguments()[index];
            return checkType(t, index);
        } else {
            String className = type == null ? "null" : type.getClass().getName();
           throw new IllegalArgumentException("Expected a Class, ParameterizedType"
                    + ", but <" + type + "> is of type " + className);
        }
    }

小結

本篇講述瞭如何獲取類或接口上的泛型類型,實際要靈活使用。上面的Type是Java語言中所有類型的公共父接口。Type有四個子類——ParameterizedTypeTypeVariableGenericArrayTypeWildcardType。在Gson等框架中有出現,有空的話,大家可以研究一下用法。

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