源码分享: 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方法
- 帅
-
缺点:
-
原始类型无法使用
-
性能有所下降
-
安全问题
-
-
包结构
-
自定义注解类
@Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface ParamAnno { String value(); } -
实体类
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(); } } } } }- 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=无}