1. 程式人生 > 其它 >Java反射用法以及isAssignableFrom()方法與instanceof關鍵字用法

Java反射用法以及isAssignableFrom()方法與instanceof關鍵字用法

這是從若依框架獲取的程式碼

  /**
     * 判斷是否需要過濾的物件。
     * 
     * @param o 物件資訊。
     * @return 如果是需要過濾的物件,則返回true;否則返回false。
     */
    @SuppressWarnings("rawtypes")
    public boolean isFilterObject(final Object o)
    {
        Class<?> clazz = o.getClass();
        if (clazz.isArray())
        {
            
return clazz.getComponentType().isAssignableFrom(MultipartFile.class); } else if (Collection.class.isAssignableFrom(clazz)) { Collection collection = (Collection) o; for (Iterator iter = collection.iterator(); iter.hasNext();) {
return iter.next() instanceof MultipartFile; } } else if (Map.class.isAssignableFrom(clazz)) { Map map = (Map) o; for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) { Map.Entry entry = (Map.Entry) iter.next();
return entry.getValue() instanceof MultipartFile; } } return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse || o instanceof BindingResult; } }

isAssignableFrom()方法與instanceof關鍵字的區別總結為以下兩個點:

  • isAssignableFrom()方法是從類繼承的角度去判斷,instanceof關鍵字是從例項繼承的角度去判斷。
  • isAssignableFrom()方法是判斷是否為某個類的父類,instanceof關鍵字是判斷是否某個類的子類。

使用方法:

父類.class.isAssignableFrom(子類.class)

子類例項 instanceof 父類型別

isAssignableFrom()方法的呼叫者和引數都是Class物件,呼叫者為父類,引數為本身或者其子類。

instanceof關鍵字兩個引數,前一個為類的例項,後一個為其本身或者父類的型別。

我們有時候需要為物件欄位設定預設值,即在別的處理中生成物件並對物件進行賦值後,有些值需要有預設值,但是又不方便通過構造方法設定的時候,我們可以通過反射配合註解來為其設定預設值而不用呼叫一堆set方法。

下面這個例子即反射配置註解為物件欄位設定預設值(包括父類),僅支援String和本型別的包裝部分包裝類(Number的子類)。
首先定義註解:

/**
 * description:
 *
 * @author wkGui
 */
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface ParamDefaultValue {
    String value();
}

定義註解的解析類:

/**
 * description:
 *
 * @author wkGui
 */
public class ParamProcessor {
    public static void applyDefaultValue(Object o) {
        Class sourceClass = o.getClass();
        //獲取物件所有欄位 包括父類
        ArrayList<Field> fields = new ArrayList<>();
        while (sourceClass != null){
            fields.addAll(Arrays.asList(sourceClass.getDeclaredFields()));
            sourceClass = sourceClass.getSuperclass();
        }

        for (Field field : fields) {
            field.setAccessible(true);
            if (field.isAnnotationPresent(ParamDefaultValue.class)) {
                try {
                    Object val = field.get(o);
                    if (val != null) {
                        continue;
                    }
                    Class type = field.getType();
                    if (type.isPrimitive()) {
                        continue;
                    }
                    String defVal = field.getAnnotation(ParamDefaultValue.class).value();

                    if (String.class.isAssignableFrom(type)) {
                        field.set(o, defVal);
                    } else if (Number.class.isAssignableFrom(type)) {
                        if (Byte.class.isAssignableFrom(type)) {
                            field.set(o, Byte.valueOf(defVal));
                        } else if (Float.class.isAssignableFrom(type)) {
                            field.set(o, Float.valueOf(defVal));
                        } else if (Short.class.isAssignableFrom(type)) {
                            field.set(o, Short.valueOf(defVal));
                        } else if (Integer.class.isAssignableFrom(type)) {
                            field.set(o, Integer.valueOf(defVal));
                        } else if (Double.class.isAssignableFrom(type)) {
                            field.set(o, Double.valueOf(defVal));
                        } else if (Long.class.isAssignableFrom(type)) {
                            field.set(o, Long.valueOf(defVal));
                        }
                    }

                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

參考連結:

https://blog.csdn.net/qq_36666651/article/details/81215221