mardi 18 janvier 2022

How to get all the fields which is annotated by my custom annotation?

I customed a field annotation to annotate the field which I want to it multiplied by scale.

I'm wandering is there a better way to get annotated fields, instead of iterating over all the fields.

It's my code below:

custom annotation:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface ShowScale {
    String scale();
}

Java object (the map is the matter):

class Vo {
    @ShowScale(scale = "0.8")
    private BigDecimal member1 = BigDecimal.ZERO;
    @ShowScale(scale = "0.8")
    private BigDecimal member2 = BigDecimal.ONE;
    @ShowScale(scale = "0.8")
    private BigDecimal member3 = BigDecimal.TEN;

    private String otherMember = "leave me alone";

    //this map is the matter...
    private Map<String, List<InnerVo>> map;

    public static class InnerVo {
        @ShowScale(scale = "0.8")
        private BigDecimal innerMember1 = BigDecimal.ZERO;
        @ShowScale(scale = "0.8")
        private BigDecimal innerMember2 = BigDecimal.ONE;
        private String otherMember = "leave me alone";

        @Override
        public String toString() {
            return new ToStringBuilder(this)
                    .append("innerMember1", innerMember1)
                    .append("innerMember2", innerMember2)
                    .append("otherMember", otherMember)
                    .toString();
        }
    }

    public Vo() {
        HashMap<String, List<InnerVo>> map = new HashMap<>();
        ArrayList<InnerVo> list = new ArrayList<>();
        list.add(new InnerVo());
        list.add(new InnerVo());
        list.add(new InnerVo());
        ArrayList<InnerVo> list1 = new ArrayList<>();
        list1.add(new InnerVo());
        list1.add(new InnerVo());
        list1.add(new InnerVo());
        ArrayList<InnerVo> list2 = new ArrayList<>();
        list2.add(new InnerVo());
        list2.add(new InnerVo());
        list2.add(new InnerVo());
        map.put("key", list);
        map.put("key1", list1);
        map.put("key2", list2);
        this.map = map;
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this)
                .append("member1", member1)
                .append("member2", member2)
                .append("member3", member3)
                .append("otherMember", otherMember)
                .append("map", map)
                .toString();
    }
}

My implement:

public class ClassTest {
    public static void main(String[] args) throws Exception {
        Vo vo = new Vo();
        System.out.println("before----->:" + vo);
        handle(vo);
        System.out.println("after----->:" + vo);
    }

    /**
     * All the fields (include in map and list) annotated by @ShowScale
     * should be multiplied by scale.
     *
     * @param obj
     */
    private static <T> void handle(T obj) {
        try {
            Class<?> clz = obj.getClass();
            String className = clz.getName();
            System.out.println("\n-------> objType:" + className);

            if (className.contains("java.util.ArrayList")) {
                for (Object o : (List) obj) {
                    handle(o);
                }
            } else if (className.contains("java.util.Map")) {
                Map map = (Map) obj;
                map.forEach((key, value) -> {
                    System.out.println(key + " :" + value);
                    handle(value);
                });
            } else {
                for (Field f : clz.getDeclaredFields()) {
                    String typeName = f.getType().getTypeName();
                    if (f.isAnnotationPresent(ShowScale.class)) {
                        f.setAccessible(true);
                        BigDecimal o = (BigDecimal) f.get(obj);
                        System.out.println("o = " + o);

                        BigDecimal scale = new BigDecimal(f.getAnnotation(ShowScale.class).scale());
                        f.set(obj, o.multiply(scale).setScale(2, RoundingMode.HALF_UP));

                    } else if (typeName.contains(Map.class.getName())) {
                        f.setAccessible(true);
                        Map map = (Map) f.get(obj);
                        map.forEach((key, value) -> {
                            System.out.println(key + " :" + value);
                            handle(value);
                        });
                    } else if (typeName.contains(List.class.getName())) {
                        f.setAccessible(true);
                        for (Object o : (List) f.get(obj)) {
                            handle(o);
                        }
                    }
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

thank you for any tips :)





Aucun commentaire:

Enregistrer un commentaire