zoukankan      html  css  js  c++  java
  • 简单自定义Annotation和利用反射获取注解中的值,反射泛型应用

    用一个简单例子,做一下自定义注解:

    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    /**
     * 
     *
     */
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotation
    {
        public String hello() default "lzyer";
      
        public String world();
    }

    Retention:表示注解保留时间和注释类型是否被保留,如果没有Retention注解的声明,是默认的RetentionPolicy.CLASS.

    从API文档中可以知道RententionPolicy是枚举类型,取值可以为CLASS,RUNTIME,SOURCE.

    CLASS:表示的是这种注解在编译时,会保存在.class文件中,JVM在运行时不会被保存

    RUNTIME:表示在编译时这种注解会保存在.class文件中,在运行时保存在JVM中,因此可以通过反射的方式调用。

    SOURCE:表示在编译的时候该注解会被丢弃。

    测试类:

    @MyAnnotation(hello = "beijing", world = "shanghai")
    public class MyTest
    {
        @MyAnnotation(hello="hunan", world="changsha")
        @Deprecated
        @SuppressWarnings("unchecked")
        public void print()
        {
            System.out.println("hello world");
        }
    }

    反射测试类:

    import java.lang.annotation.Annotation;
    import java.lang.reflect.Method;
     
    public class Myflection
    {
        public static void main(String[] args)throws Exception
        {
            MyTest myTest = new MyTest();
            
            Class<MyTest> classType = MyTest.class;
            
            Method method = classType.getMethod("print", new Class[]{});
            //查看某个方法是否存在该注解
             if(method.isAnnotationPresent(MyAnnotation.class))
             {
                 MyAnnotation myAnnotation =  method.getAnnotation(MyAnnotation.class);
                 String hello = myAnnotation.hello();
                 String world = myAnnotation.world();
                 System.out.println(hello +", " +world);
             }
             //得到方法的所有注解,并遍历
             Annotation[] annotations =  method.getAnnotations();
             for(Annotation a : annotations)
             {
                 System.out.println(a);
             }
        }
    }

    结果:

    应用:

    要返回的List中存放的实体类型中字段与sql查出来的字段无需完全匹配,字段多了少了都不影响,sql中查询出来的字段能与实体中的属性中get方法内的@Column中的name属性对应上即可。

        /**
         * 根据传入sql以及返回值的类型
         * @param sql:需要执行查询的sql语句
         * @param clas:实体类型(例如:MyEntity.class)
         * @return
         * @throws Exception
         */
        public static <T> List<T> findBySql(String sql, Class<T> clas) throws Exception {
            List<T> list = new ArrayList<T>();
            SystemService systemService = (SystemService)SpringTool.getBean("systemService");
            List<Map<String,Object>> dataList = systemService.findForJdbc(sql);
            
            for (Map<String, Object> map : dataList) {
                //泛型类实例化
                T t = clas.newInstance();
                for (String key : map.keySet()) {
                    //当前实体对象中是否存在当前字段对应的属性,如果不存在则continue;
                    boolean flag = false;
                    // 获取属性的名字
                    String name = "";
                    Field field = null;
                    Field[] fields = clas.getDeclaredFields();
                    for (int i = 0; i < fields.length; i++) {
                        field = fields[i];
                        // 获取属性的名字
                        name = field.getName();
                        // 将属性的首字符大写,方便构造get,set方法
                        name = name.substring(0, 1).toUpperCase() + name.substring(1);
                        Method m = t.getClass().getDeclaredMethod("get" + name);
                        //查看某个方法是否存在该注解
                            if(m.isAnnotationPresent(Column.class)){
                                Column column =  m.getAnnotation(Column.class);
                                String columnName = column.name();
                                if (key.equalsIgnoreCase(columnName)) {
                                    flag = true;
                                    break;
                            }
                            }
                    }
                    if (flag) {
                        // 将属性的首字符大写,方便构造get,set方法
                        name = name.substring(0, 1).toUpperCase() + name.substring(1);
                        // 获取属性的类型
                        String type = field.getGenericType().toString();
                        // 如果type是类类型,则前面包含"class ",后面跟类名
                        if (type.equals("class java.lang.String")) {
                            String value = map.get(key)==null?"":map.get(key).toString();
                            Method n = t.getClass().getDeclaredMethod("set" + name,String.class);
                            n.invoke(t,value);  
                        }
                        if (type.equals("class java.lang.Integer")) {
                            Integer value = map.get(key)==null?0:Integer.parseInt(map.get(key).toString());
                            Method n = t.getClass().getDeclaredMethod("set" + name,Integer.class);
                            n.invoke(t,value); 
                        }
                        if (type.equals("class java.lang.Short")) {
                            Short value = map.get(key)==null?Short.parseShort("0"):Short.parseShort(map.get(key).toString());
                            Method n = t.getClass().getDeclaredMethod("set" + name,Short.class);
                            n.invoke(t,value); 
                        }
                        if (type.equals("class java.lang.Double")) {
                            Double value = map.get(key)==null?0.00:Double.parseDouble(map.get(key).toString());
                            Method n = t.getClass().getDeclaredMethod("set" + name,Double.class);
                            n.invoke(t,value); 
                        }
                        if (type.equals("class java.lang.Boolean")) {
                            Boolean value = map.get(key)==null?false:(Boolean)map.get(key);
                            Method n = t.getClass().getDeclaredMethod("set" + name,Boolean.class);
                            n.invoke(t,value); 
                        }
                        if (type.equals("class java.util.Date")) {
                            Date value = map.get(key)==null?null:(Date)map.get(key);
                            Method n = t.getClass().getDeclaredMethod("set" + name,Date.class);
                            n.invoke(t,value); 
                        }
                    }
                }
                list.add(t);
            }
            return list;
        }
  • 相关阅读:
    2017年11月01日普及组 I Got a Matrix!
    2017年10月21日普及组 简单单词
    2017年10月21日普及组 排名
    2017年10月18日普及组 文件名排序
    2017年10月18日普及组 面积最大
    2017年10月08日 上学
    [APIO2010]特别行动队
    斜率优化DP(学习笔记)
    [HNOI2008]玩具装箱TOY
    皇宫看守
  • 原文地址:https://www.cnblogs.com/shuilangyizu/p/14944892.html
Copyright © 2011-2022 走看看