反射和注解

反射的使用和效率测试

  • 反射的使用

    /**
         * 反射的使用
         */
        public static void testUse() throws Exception {
    
            Class<?> UserClass = Class.forName("com.phil.RATest.User");
            //获得有参构造方法
            Constructor<?> constructor = UserClass.getDeclaredConstructor(int.class, int.class, String.class, int.class);
            //调用有参构造方法
            User user = (User)constructor.newInstance(18,1,"小明",11);
            //输出对象
            System.out.println(user);
            //获取方法
            Method testMethod = UserClass.getDeclaredMethod("testMethod", String.class);
            //方法调用
            //私有方法调用需要设置权限
            testMethod.setAccessible(true);
            testMethod.invoke(user, "你好啊");
    
            //获取私有属性
            Field age = UserClass.getDeclaredField("age");
            //私有变量赋值需要设置权限
            age.setAccessible(true);
            age.set(user, 20);
            System.out.println(user.getAge());
        }
    
  • 反射效率测试

    验证普通new对象获取属性,反射获取对象属性,以及检测关闭下的反射获取对象属性,三种方式10亿次调用获取属性方法的性能问题;

    //普通方式调用
        public static void test01(){
            //普通方式调用
            User user = new User();
            long st = System.currentTimeMillis();
    
            for (int i = 0; i < 1000000000; i++) {
                user.getName();
            }
    
            long et = System.currentTimeMillis();
    
            System.out.println("普通方式执行时间:" + (et - st) + "ms");
    
        }
        //反射方式调用
        public static void test02() throws Exception {
            Class<?> c1 = Class.forName("com.phil.RATest.User");
            User user = (User) c1.newInstance();
            Method getName = c1.getDeclaredMethod("getName");
    
            long st = System.currentTimeMillis();
    
            for (int i = 0; i < 1000000000; i++) {
                getName.invoke(user,null);
            }
    
            long et = System.currentTimeMillis();
    
            System.out.println("反射方式执行时间:" + (et - st) + "ms");
    
        }
        //反射方式调用  关闭检测
        public static void test03() throws Exception {
            Class<?> c1 = Class.forName("com.phil.RATest.User");
            User user = (User) c1.newInstance();
            Method getName = c1.getDeclaredMethod("getName");
            //关闭检测
            getName.setAccessible(true);
            long st = System.currentTimeMillis();
    
            for (int i = 0; i < 1000000000; i++) {
                getName.invoke(user,null);
            }
    
            long et = System.currentTimeMillis();
    
            System.out.println("关闭检测执行时间:" + (et - st) + "ms");
    
        }
    

注解和反射获取注解

  • 注解的使用

    1. 注解的格式

      @interface 注解名{

      ​ 类型 字段名称();

      }

    2. 注解的四个关键词

      • @Target:目标,一般使用METHOD(方法),TYPE(类),FIELD(属性)等
      • @Retention:保存该注解的级别(RUNTIME>CLASS>SOURCE)
      • @Documented
    3. 例子

      //目标
      @Target(ElementType.METHOD)
      //runtime>class>source
      @Retention(RetentionPolicy.RUNTIME)
      //文档
      @Documented
      //继承
      @Inherited
      @interface MyAnnotation{
          String name() default "Phil";
      
          int age();
      }
      
  • 反射获取注解

    package com.phil.RATest;
    
    import java.lang.annotation.*;
    import java.lang.reflect.Field;
    
    public class Test02 {
    
        public static void main(String[] args) throws NoSuchFieldException {
            Class<Student> c1 = Student.class;
    
            //获取所有注解
            Annotation[] annotations = c1.getAnnotations();
            for (Annotation annotation : annotations) {
                System.out.println(annotation);
            }
    
            //获取指定类的注解
            MyStudentAnnotation annotation = c1.getAnnotation(MyStudentAnnotation.class);
            System.out.println(">" + annotation);
            //通过反射获取value值
            String value = annotation.value();
            System.out.println("value=" + value);
    
            //获取属性的注解
            Field f = c1.getDeclaredField("name");
            PropertyAnnotation annotation1 = f.getAnnotation(PropertyAnnotation.class);
            System.out.println("columnName=" + annotation1.columnName() + " type=" + annotation1.type() + " length=" + annotation1.length());
    
            f = c1.getDeclaredField("age");
            PropertyAnnotation annotation2 = f.getAnnotation(PropertyAnnotation.class);
            System.out.println("columnName=" + annotation2.columnName() + " type=" + annotation2.type() + " length=" + annotation2.length());
    
            f = c1.getDeclaredField("id");
            PropertyAnnotation annotation3 = f.getAnnotation(PropertyAnnotation.class);
            System.out.println("columnName=" + annotation3.columnName() + " type=" + annotation3.type() + " length=" + annotation3.length());
        }
    
    }
    
    
    //学生类
    @MyStudentAnnotation(value = "db_student")
    class Student{
        @PropertyAnnotation(columnName = "db_id",type = "int", length = 10)
        private int id;
        @PropertyAnnotation(columnName = "db_age", type = "int", length = 10)
        private int age;
        @PropertyAnnotation(columnName = "db_name", type = "varchar", length = 3)
        private String name;
    
        public Student() {
        }
    
        public Student(int id, int age, String name) {
            this.id = id;
            this.age = age;
            this.name = name;
        }
    }
    
    //类名的注解
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @interface MyStudentAnnotation{
        String value();
    }
    
    //属性的注解
    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    @interface PropertyAnnotation{
        String columnName();
        String type();
        int length();
    }
    
posted @ 2020-11-26 11:17  PhilXiao  阅读(108)  评论(0)    收藏  举报