java 反射中的坑

1 class 中的getMethod , getField , getDeclaredField,getDeclaredMethods 區別

get打頭的可以獲取當前類以及父類或者接口中聲明的public 修飾的字段或者是方法

getDeclared 只能獲取當前類中聲明的所有方法或者是字段,包括private , protected ,public ,以及默認的包修飾符。

2 fianl 字段可以修改嗎

可以通過反射來進行修改,如果被final 修飾的字段同時被static 修飾,那麼只有類加載器可以修改,反射此時也修改不了

3 type 相關知識

https://www.jianshu.com/p/0f3eda48d611

4 關於範型的反射

public class Main {

    public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
        Class<Children> clazz = Children.class;
        Method get = clazz.getMethod("get");
        Class<?> returnType = get.getReturnType();
        System.out.println(returnType.getName());
    }
}

class Parent<T> {
    public T get() {
        return null;
    }
}

class Children extends Parent<String> {

}

對於上述的代碼,結果爲java.lang.Object 而不是java.lang.String, 如果我們想要獲取爲String類型,需要用到第三個知識點,type的相關知識進行獲取。

以下爲簡單的代碼

public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
        Class<Children> clazz = Children.class;
        Method getMethod = clazz.getMethod("get");
        Type getMethodReturnType = getMethod.getGenericReturnType();
        Class<?> returnType = getMethod.getReturnType();
        //如果返回值是TypeVariable,需要從父類中找到對應的TypeVariable數組並賦值
        if(getMethodReturnType instanceof TypeVariable){
            Type superclassType = clazz.getGenericSuperclass();
            Class superClass = clazz.getSuperclass();
            if(superclassType instanceof ParameterizedType){
                ParameterizedType superType = (ParameterizedType)superclassType;
                
                TypeVariable[] typeParameters = superClass.getTypeParameters();
                
                Type[] actualTypeArguments = superType.getActualTypeArguments();
                for (int i = 0; i < typeParameters.length; i++) {
                    TypeVariable  typeVariable = typeParameters[i];
                    if(getMethodReturnType.equals(typeVariable)){
                        returnType = (Class<?>) actualTypeArguments[i];
                    }

                }
            }
        }


        System.out.println(returnType.getName());
    }
}

在mybatis 中TypeParameterResolver 類中,可以很好的支持複雜範型,繼承的類型解析問題。

5 數組類型的解析

對於數組類型來說,一共有倆種情況,一種是由基本類型組成的數組,一種由對象類型組成的數組,接下來我們來看一個根據數組和對象下標返回對應的值,這裏我們將Map 和List也一併加入。

public Object getCollectionValue(String index, Object collection) {
        //如果是map ,index 爲key
        if (collection instanceof Map) {
            return ((Map) collection).get(index);
        //爲集合,index 爲下標
        } else {
            int i = Integer.parseInt(index);
            if (collection instanceof List) {
                return ((List) collection).get(i);
            // 對象類型數組都可以通過 collection instanceof Object[] 這條語句來判斷
            } else if (collection instanceof Object[]) {
                return ((Object[]) collection)[i];
            } else if (collection instanceof char[]) {
                return ((char[]) collection)[i];
            } else if (collection instanceof boolean[]) {
                return ((boolean[]) collection)[i];
            } else if (collection instanceof byte[]) {
                return ((byte[]) collection)[i];
            } else if (collection instanceof double[]) {
                return ((double[]) collection)[i];
            } else if (collection instanceof float[]) {
                return ((float[]) collection)[i];
            } else if (collection instanceof int[]) {
                return ((int[]) collection)[i];
            } else if (collection instanceof long[]) {
                return ((long[]) collection)[i];
            } else if (collection instanceof short[]) {
                return ((short[]) collection)[i];
            } else {
                throw new IllegalArgumentException("The '" + index + "' property of " + collection + " is not a List or Array.");
            }
        }
    }

 

 

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