java中isAssignableFrom()方法与instanceof关键字用法及通过反射配合注解为字段设置默认值

.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();
                }
            }
        }
    }
}


  • 53
    点赞
  • 165
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
好的,这里是一个简单的实现示例: 首先,我们需要定义一个注解类 `DefaultValue` ,用于标记需要设置默认值的属性。 ```java @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface DefaultValue { String value(); } ``` 接下来,我们可以定义一个拦截器类 `DefaultValueInterceptor` ,用于在接收对象时拦截并设置默认值。 ```java public class DefaultValueInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (handler instanceof HandlerMethod) { HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); Parameter[] parameters = method.getParameters(); for (Parameter parameter : parameters) { // 判断参数是否是一个对象 if (parameter.getType().isAssignableFrom(Object.class)) { Object requestBody = request.getAttribute("requestBody"); if (requestBody != null) { Field[] fields = requestBody.getClass().getDeclaredFields(); for (Field field : fields) { DefaultValue defaultValueAnnotation = field.getAnnotation(DefaultValue.class); if (defaultValueAnnotation != null) { field.setAccessible(true); Object fieldValue = field.get(requestBody); // 如果字段为空,则设置默认值 if (fieldValue == null) { field.set(requestBody, defaultValueAnnotation.value()); } } } } } } } return true; } } ``` 在上面的示例,我们使用了 Spring MVC 框架,因此可以通过实现 `HandlerInterceptor` 接口来实现请求拦截器。在 `preHandle()` 方法,我们首先判断处理程序是否是一个方法,然后获取方法的所有参数。对于每个参数,我们判断它是否是一个对象,并且是否被 `@RequestBody` 注解标记。如果是,我们就获取该对象的所有属性,并对每个属性进行判断,看它是否被 `@DefaultValue` 注解标记。如果是,我们就将该属性设置默认值。 最后,我们需要在 Spring MVC 配置文件注册拦截器: ```xml <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.example.interceptor.DefaultValueInterceptor"/> </mvc:interceptor> </mvc:interceptors> ``` 在上面的配置,我们将 `DefaultValueInterceptor` 注册为一个拦截器,并将它应用到所有请求路径上。 这样,当我们接收到一个对象时,如果它的某些属性为空,则会自动设置默认值。例如,我们可以给一个名为 `user` 的对象的 `name` 属性设置默认值: ```java public class User { @DefaultValue("Anonymous") private String name; // ... } ``` 当我们接收到一个空的 `User` 对象时,它的 `name` 属性就会被设置为 "Anonymous"。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值