注解+反射帅气的完成默认值设置

648 阅读1分钟

源码分享: github.com/ddb12138/ju…

涉及isAssignableForm、注解、反射完成默认值的设置

isAssignableForm方法与instanceof关键字的区别

继承角度判断类型
isAssignableForm类继承的角度判断是否为某个类的父类
instanceof实例继承的角度判断是否某个类的子类

讲解:

父类.class.isAssignableFrom(子类.class)

子类实例 instanceof 父类类型 ==>用来确定该实例是否是父类的一个实例

代码:

public class Main1 {
    public static void main(String[] args) {
        
        //1.是父类
        boolean isFlag = Number.class.isAssignableFrom(Double.class);
        System.out.println(isFlag);
        //输出:true
        
	//2.是本身
        boolean isFlag1 =Double.class.isAssignableFrom(Number.class);
        System.out.println(isFlag1);
        //输出:true
		
        //3.是子类
        boolean isFlag2 =Double.class.isAssignableFrom(Double.class);
        System.out.println(isFlag2);
        //输出:false

        //子类实例 instanceof 父类类型
        Object object1 = new ArrayList<>();
        if (object1 instanceof ArrayList) {
            System.out.println("我是ArrayList的实例");
            //输出:我是ArrayList的实例
        }
    }
}

注解类+反射+isAssignableForm完成注入

使用场景:为对象字段设置默认值,不想修改构造器,不想使用set方法?

涉及自定义注解类实体类处理器类,重点是 处理器类

  • 优点:

    • 不涉及构造器
    • 没有使用到set方法
  • 缺点:

    • 原始类型无法使用

    • 性能有所下降

    • 安全问题

  1. 包结构

  2. 自定义注解类

    @Target({ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Documented
    public @interface ParamAnno {
        String value();
    }
    
  3. 实体类

    public class Person {
        @ParamAnno(value = "ddb12138")
        private String name;
        @ParamAnno(value = "13")
        private Integer age;
        @ParamAnno(value = "20.2d")
        private Double money;
        @ParamAnno(value = "true")
        private Boolean man;
        @ParamAnno(value = "郭")
        private Character lastName='无';
        public Person() {
        }
    
        //get&set方法
        //toString方法
     	......
    

    4.处理器类

    public class ParamProcessor {
        public static void setDefalutValue(Object obj) {
            //先获取传进来的类Class
            Class source = obj.getClass();
            ArrayList<Field> fields = new ArrayList<>();
            while (source != null) {
                //获取所有属性(包括私有属性)
                fields.addAll(Arrays.asList(source.getDeclaredFields()));
                source = source.getSuperclass();
            }
            for (Field field : fields) {
                //设置放开权限
                field.setAccessible(true);
                //判断是否该属性有注解
                if (field.isAnnotationPresent(ParamAnno.class)) {
                    try {
                        //返回指定对象上此 Field 表示的字段的值
                        Object val = field.get(obj);
                        //可以通过判断语句来选择注入对象是否是空值(即原本有值的话要不要覆盖上注解的值),可以注意最后输出lastName的值
                        if (val != null) {
                            continue;
                        }
                        //获取该属性的种类
                        Class type = field.getType();
                        if (type.isPrimitive()) {
                            //判断是否为原始类(boolean,char,byte,short,int,long,float,double)
                            continue;
                        }
                        //获取注解上的值
                        String defVal = field.getAnnotation(ParamAnno.class).value();
                        if (String.class.isAssignableFrom(type)) {
                            field.set(obj, defVal);
                        } else if (Number.class.isAssignableFrom(type)) {
                            if (Byte.class.isAssignableFrom(type)) {
                                field.set(obj, Byte.valueOf(defVal));
                            } else if (Float.class.isAssignableFrom(type)) {
                                field.set(obj, Float.valueOf(defVal));
                            } else if (Short.class.isAssignableFrom(type)) {
                                field.set(obj, Short.valueOf(defVal));
                            } else if (Double.class.isAssignableFrom(type)) {
                                field.set(obj, Double.valueOf(defVal));
                            } else if (Integer.class.isAssignableFrom(type)) {
                                field.set(obj, Integer.valueOf(defVal));
                            } else if (Long.class.isAssignableFrom(type)) {
                                field.set(obj, Long.valueOf(defVal));
                            }
                        }else if (Boolean.class.isAssignableFrom(type)){
                            field.set(obj,Boolean.valueOf(defVal));
                        }else if (Character.class.isAssignableFrom(type)){
                            field.set(obj,Character.valueOf(defVal.charAt(0)));
                        }
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
    
    1. Main方法
    public class Main {
        public static void main(String[] args) {
            Person person = new Person();
            ParamProcessor.setDefalutValue(person);
            System.out.println(person);
        }
    }
    
    输出:
    Person{name='ddb12138', age=13, money=20.2, man=true, lastName=无}