zoukankan      html  css  js  c++  java
  • 反射 reflect

    java类的加载
      java类的加载是指将.class文件(可能在磁盘,也可能在网络)加载到内存中,并为之生成java.lang.class对象的实例
      java中类以其全限定包名作为唯一标识,jvm中则以全限定包名和类加载器作为唯一标识。
      jvm中的类加载器有三个层次:根类加载器、扩展类加载器、系统类加载器。分别加载核心类,扩展jar包中的类以及classpath等指定的类
      对象具有两种类型:编译时类型和运行时类型。

    1:功能

      获取类的各个部位对应的对象  

          Class       类
          Constructor    构造器
          Method      方法
          Field       属性
          Annotation    注解

     

     2: 对象准备

      2.1 类对象
    @Data
    public class User {
    
        private Integer id;
       @NotBeNull
    public String userName; private String sex; private Integer grade; //年级 private List<Course> courseList; //课程 private User() { } public User(Integer id) { findById(id); } public User(Integer id, String userName, String sex, Integer grade) { this.id = id; this.userName = userName; this.sex = sex; this.grade = grade; courseList = new ArrayList<>(); } private User findById(Integer id) { return Utils.getUserById(id); } public List<User> listAll() { return Utils.getUsers(); } }

      2.2 接口

    /**
     * 测试匿名类
     * 匿名类: 匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承一个父类,或实现一个接口
     * 匿名内部类不能定义构造器。由于匿名内部类没有类名,所以无法定义构造器,但匿名内部类可以初始化块,可以通过初始化块来完成构造器需要完成的工作。
     */
    public interface AnonymousInterface {
        String print(String msg);
    }

      2.3 枚举

    /**
     * 枚举
     */
    public enum StatusEnum {}

      2.4 注解

    /**
     * 注解
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)          //注解作用到属性上
    public @interface NotBeNull {
      
    String value() default "zsc";
    }

      2.5 工具

    public class Utils {
    
        public static List<User> getUsers() {
            User user1 = new User(1, "小夏1", "男", 1);
            User user2 = new User(2, "小夏2", "男", 2);
            User user3 = new User(3, "小夏3", "男", 3);
            User user4 = new User(4, "小夏4", "男", 4);
            List<User> users = Arrays.asList(user1, user2, user3, user4);
            return users;
        }
    
    
        public static User getUserById(final Integer id) {
    
            List<User> users = Utils.getUsers();
    
            for (User user : users) {
                if (user.getId().intValue() == id) {
                    return user;
                }
            }
            return null;
        }
    
        public static List<Course> getCourses(){
            Course course1 = new Course(1,"数学","张老师");
            Course course2 = new Course(2,"英语","刘老师");
            Course course3 = new Course(3,"汉语","王老师");
            Course course4 = new Course(4,"法语","宋老师");
            List<Course> courses = Arrays.asList(course1, course2, course3, course4);
            return courses;
        }
    
    
        public static Course getCourseById( Integer id) {
    
            List<Course> courses = Utils.getCourses();
    
            for (Course course : courses) {
                if (course.getId().intValue() == id) {
                    return course;
                }
            }
            return null;
        }
    }

    3:反射获取信息

    package com.draymond.reflect;
    
    import com.draymond.reflect.entity.User;
    import org.junit.Test;
    
    import java.lang.annotation.Annotation;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    /**
     * 反射获取类的方式
     */
    public class MainTest {
    
    //-----------------------------   获得类相关的方法   -------------------------------
    
        /**
         * 获取Class
         *
         * @throws ClassNotFoundException
         */
        @Test
        public void test1() throws ClassNotFoundException {
            Class clazz1 = Class.forName("com.draymond.reflect.entity.User");
            System.out.println(clazz1);     //结果:class com.draymond.reflect.entity.User
    
            User user = new User(1, "小夏1", "男", 1);
            Class clazz2 = user.getClass();
            System.out.println(clazz2);      //结果:class com.draymond.reflect.entity.User
    
            Class clazz3 = User.class;
            System.out.println(clazz3);      //结果:class com.draymond.reflect.entity.User
        }
    
        /**
         * 获取类的全路径
         */
        @Test
        public void test2() throws Exception {
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
            String name = clazz.getName();
            System.out.println(name);   //com.draymond.reflect.entity.User
        }
    
        /**
         * 获取包的路径
         */
        @Test
        public void test3() throws Exception {
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
            Package clazzPackage = clazz.getPackage();
            String packageName = clazzPackage.getName();
            System.out.println(packageName);        //com.draymond.reflect.entity
        }
    
        /**
         * 获取类的名称
         */
        @Test
        public void test4() throws Exception {
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
            String simpleName = clazz.getSimpleName();
            System.out.println(simpleName);     // User
        }
    
        /**
         * 获得当前类继承的父类的名字
         *
         * @throws Exception
         */
        @Test
        public void test5() throws Exception {
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
            Class superclass = clazz.getSuperclass();
            System.out.println(superclass); // class java.lang.Object
        }
    
        /**
         * 获得当前类实现的类或是接口
         *
         * @throws Exception
         */
        @Test
        public void test6() throws Exception {
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
            Class[] interfaces = clazz.getInterfaces();
    
            for (Class superclass : interfaces) {
                System.out.println(superclass);     // class java.lang.Object
            }
        }
    
    
    //-----------------------------   获得类中属性相关的方法   -------------------------------
    
        /**
         * 获取所有的public修饰的属性
         *
         * @throws Exception
         */
        @Test
        public void test7() throws Exception {
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
            Field[] fields = clazz.getFields();
            System.out.println(fields.length);
            for (Field field : fields) {
                String fieldName = field.getName();
                System.out.println("fieldName==" + fieldName);    //userName
    
    //            boolean aBoolean = field.getBoolean(Integer.class);   //field是String类型,不能转为boolean
    //            System.out.println(aBoolean);
    
                Class<?> type = field.getType();
    
                String name = type.getName();   // java.lang.String
                System.out.println(name);
    
            }
        }
    
        /**
         * 获取所有属性(包括私有)
         *
         * @throws Exception
         */
        @Test
        public void test8() throws Exception {
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);          //暴力可见
    
                String fieldName = field.getName(); //获取属性的名称
                Class<?> type = field.getType();    //获取属性的类型
                String typeName = type.getName();
            }
        }
    
    
    //-------------------------------  获得类中 Annotation注解 相关的方法 ------------------------
    
        /**
         * 获取该 类,方法,属性,构造器 上的公有注解对象
         * <p>
         * 获取 User类上标注的 NotBeNull 注解
         *
         * @throws Exception
         */
        @Test
        public void test9() throws Exception {
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
    
            Annotation annotation = clazz.getAnnotation(NotBeNull.class);   //获取 User类上标注的 NotBeNull 注解
            if (annotation == null) {
                System.out.println("没有从user中获取到 NotBeNull 注解");    // 备注:没有执行(因为User类上加了该注解)
            } else {
                System.out.println("从user中获取到 NotBeNull 注解");       // 从user中获取到 NotBeNull 注解
            }
        }
    
        /**
         * 返回该 类,方法,属性,构造器 所有的公有注解对象
         *
         * @throws Exception
         */
        @Test
        public void test11() throws Exception {
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
            Annotation[] annotations = clazz.getAnnotations();
            for (Annotation annotation : annotations) {
                Class<? extends Annotation> annotationType = annotation.annotationType();
                String name = annotationType.getName();
                String simpleName = annotationType.getSimpleName();
                System.out.println("name:" + name);             // name:com.draymond.reflect.NotBeNull
                System.out.println("simpleName:" + simpleName); // simpleName:NotBeNull
            }
        }
    
    
        /**
         * 获取所有注解(包括非public修饰)
         * 没意义:注解就是public修饰的
         *
         * @throws Exception
         */
        @Test
        public void test12() throws Exception {
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
            Annotation[] declaredAnnotations = clazz.getDeclaredAnnotations();  //获取
        }
    
    //------------------------------  获得类中构造器相关的方法  ------------------------------
    
        /**
         * 获取 private 空参构造器
         *
         * @throws Exception
         */
        @Test
        public void test13() throws Exception {
    
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
            Constructor constructor = clazz.getConstructor();   //构造器private
            String constructorName = constructor.getName();
            System.out.println(constructorName);                //  java.lang.NoSuchMethodException: com.draymond.reflect.entity.User.<init>()
        }
    
        /**
         * 获取 public 实参构造器
         *
         * @throws Exception
         */
        @Test
        public void test14() throws Exception {
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
            Constructor constructor = clazz.getConstructor(Integer.class, String.class, String.class, Integer.class);
            String constructorName = constructor.getName();
            System.out.println(constructorName);    // com.draymond.reflect.entity.User
        }
    
        /**
         * 获取private 构造器
         *
         * @throws Exception
         */
        @Test
        public void test15() throws Exception {
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
            Constructor declaredConstructor = clazz.getDeclaredConstructor();
            declaredConstructor.setAccessible(true);        //暴力破解
            String constructorName = declaredConstructor.getName();
            System.out.println(constructorName);            // com.draymond.reflect.entity.User
        }
    
        /**
         * 获得该类所有构造方法
         *
         * @throws Exception
         */
        @Test
        public void test16() throws Exception {
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
            Constructor[] constructors = clazz.getDeclaredConstructors();
            for (Constructor constructor : constructors) {
                String constructorName = constructor.getName();
                System.out.println(constructorName);
            }
        }
    
        //-----------------------  实例化对象 ---------------------------
    
        /**
         * class不能获取private修饰构造器对应的实例
         *
         * @throws Exception
         */
        @Test
        public void test17() throws Exception {
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
            User user = (User) clazz.newInstance();  // java.lang.IllegalAccessException: Class com.draymond.reflect.MainTest can not access a member of class com.draymond.reflect.entity.User with modifiers "private"
            System.out.println(user);
        }
    
        /**
         * 通过构造器获取private修饰构造器对应的实例
         *
         * @throws Exception
         */
        @Test
        public void test18() throws Exception {
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
            Constructor declaredConstructor = clazz.getDeclaredConstructor();
            declaredConstructor.setAccessible(true);
            User user = (User) declaredConstructor.newInstance();
            System.out.println(user);   // User(id=null, userName=null, sex=null, grade=null, courseList=null)
        }
    
        /**
         * 通过构造器获取带参构造器对应的实例
         *
         * @throws Exception
         */
        @Test
        public void test19() throws Exception {
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
            Constructor declaredConstructor = clazz.getDeclaredConstructor(Integer.class, String.class, String.class, Integer.class);
            declaredConstructor.setAccessible(true);
            User user = (User) declaredConstructor.newInstance(1, "王老师", "数学", 1);
            System.out.println(user);   // User(id=1, userName=王老师, sex=数学, grade=1, courseList=[])
    
            // 备注:getDeclaredConstructor()参数的类型与个数 与 newInstance 类型与个数 一致
        }
    
    
    //-----------------------  获得类中方法相关的方法 ---------------------
    
        /**
         * 获取所有的方法(包括private)
         *
         * @throws Exception
         */
        @Test
        public void test20() throws Exception {
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
            Method[] methods = clazz.getDeclaredMethods();
    
            for (Method method : methods) {
                String methodName = method.getName();
                System.out.print(methodName + "  ");  // equals  toString  hashCode  getId  getUserName  canEqual  listAll  setSex  setGrade  getCourseList  setUserName  setCourseList  findById  getSex  getGrade  setId
            }
        }
    
        /**
         * 获取单个指定方法
         *
         * @throws Exception
         */
        @Test
        public void test21() throws Exception {
    
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
            // 获取 find 方法,指定参数类型为Integer
            Method methods = clazz.getDeclaredMethod("findById", Integer.class);
            methods.setAccessible(true);
            Constructor constructor = clazz.getDeclaredConstructor();
            constructor.setAccessible(true);
            User user = (User) constructor.newInstance();
    
            // 由于 空参构造器是private,所以不能创建实例
            User invoke = (User) methods.invoke(user, 1);
            System.out.println(invoke);
        }
    
        /**
         * 强行获取私有构造器对象
         *
         * @throws Exception
         */
        @Test
        public void test22() throws Exception {
    
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
            // 获取 find 方法,指定参数类型为Integer
            Method methods = clazz.getDeclaredMethod("findById", Integer.class);
    
            Constructor declaredConstructor = clazz.getDeclaredConstructor();
            User user = (User) declaredConstructor.newInstance();
            System.out.println(user);   // User(id=null, userName=null, sex=null, grade=null, courseList=null)
    
        }
    
    //-------------------------------  类中其他重要的方法  --------------------
    
        /**
         * 是否为注解
         *
         * @throws Exception
         */
        @Test
        public void test23() throws Exception {
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
            boolean userIsAnnotation = clazz.isAnnotation();
            System.out.println("userIsAnnotation  :  " + userIsAnnotation);    // false
    
            Class notBeNullClazz = Class.forName("com.draymond.reflect.NotBeNull");
            boolean notBeNullIsAnnotation = notBeNullClazz.isAnnotation();
            System.out.println("notBeNullIsAnnotation  :  " + notBeNullIsAnnotation);    // true
        }
    
        /**
         * 指定注解是否存在指定元素上
         *
         * @throws Exception
         */
        @Test
        public void test24() throws Exception {
    
            Class userClazz = Class.forName("com.draymond.reflect.entity.User");
            boolean annotationPresent = userClazz.isAnnotationPresent(NotBeNull.class);
            System.out.println(annotationPresent);  // true
        }
    
        /**
         * 是否为匿名类
         *
         * @throws Exception
         */
        @Test
        public void test25() throws Exception {
    
            AnonymousInterface anonymousInterface = new AnonymousInterface() {
                @Override
                public String print(String msg) {
                    System.out.println(msg);
                    return msg;
                }
            };
            Class clazz = anonymousInterface.getClass();
            boolean anonymousClass = clazz.isAnonymousClass();
            System.out.println(anonymousClass);     // true
    
        }
    
        /**
         * 是否为数组
         *
         * @throws Exception
         */
        @Test
        public void isArray() throws Exception {
            char[] chars = new char[10];
    
            Class clazz = chars.getClass();
            boolean array = clazz.isArray();
            System.out.println(array);
        }
    
        /**
         * 是否为 枚举
         *
         * @throws Exception
         */
        @Test
        public void isEnum() throws Exception {
            Class clazz = StatusEnum.class;
            boolean anEnum = clazz.isEnum();
            System.out.println(anEnum); //true
        }
    
        /**
         * 是否为**的实例
         *
         * @throws Exception
         */
        @Test
        public void isInstance() throws Exception {
    
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
    
            User user = new User(1, "zsc", "男", 1);
    
            boolean instance = clazz.isInstance(user);
            System.out.println(instance);   //true
        }
    
        /**
         * 是否为接口
         *
         * @throws Exception
         */
        @Test
        public void isInterface() throws Exception {
            Class clazz = AnonymousInterface.class;
            boolean anInterface = clazz.isInterface();
            System.out.println(anInterface);
        }
    
        /**
         * 是否为局部类
         *
         * @throws Exception
         */
        @Test
        public void isLocalClass() throws Exception {
    
    
        }
    
        /**
         * 是否为内部类
         *
         * @throws Exception
         */
        @Test
        public void isMemberClass() throws Exception {
        }
    //-------------------------  Field类  ----------------------------
    
        /**
         * 属性与obj相等则返回true(obj是属性名,而不是属性类型)
         *
         * @throws Exception
         */
        @Test
        public void test32() throws Exception {
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
            Field userName = clazz.getDeclaredField("userName");
            userName.setAccessible(true);
            boolean isString = userName.equals(String.class);   // false
    
            boolean isUserName = userName.equals(userName);
            System.out.println(isString);       // false
            System.out.println(isUserName);     // true
    
        }
    
        /**
         * get属性值
         *
         * @throws Exception
         */
        @Test
        public void test33() throws Exception {
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
    
            Constructor constructor = clazz.getDeclaredConstructor();
            constructor.setAccessible(true);
            User user = (User) constructor.newInstance();
            user.setUserName("draymond");
            Field userName = clazz.getDeclaredField("userName");
            userName.setAccessible(true);
            Object o1 = userName.get(user);
            System.out.println(o1); // draymond
        }
    
        /**
         * set属性值
         *
         * @throws Exception
         */
        @Test
        public void test34() throws Exception {
    
            Class clazz = Class.forName("com.draymond.reflect.entity.User");
    
            Constructor constructor = clazz.getDeclaredConstructor();
            constructor.setAccessible(true);
            Object o = constructor.newInstance();
    
            Field userName = clazz.getDeclaredField("userName");
            userName.setAccessible(true);
            userName.set(o, "zsc");
    
            System.out.println(o);  // User(id=null, userName=zsc, sex=null, grade=null, courseList=null)
    
        }
    
        /**
         * 获取注解上的值
         *
         * @throws Exception
         */
        @Test
        public void test35() throws Exception {
            Class clazz = User.class;
            Field userNameField = clazz.getDeclaredField("userName");
            NotBeNull annotation = userNameField.getAnnotation(NotBeNull.class);
            String value = annotation.value();
            System.out.println(value);  //zsc
        }
    
     
    
    }
      注解开发: https://www.cnblogs.com/draymond/p/12499670.html

     5:aop+注解+反射  自动对数据库查询不到的值赋值

    
    

        (订单详情页面:订单信息+用户信息 

         单表查订单详情,没有用户信息的;使用代理的方式,自动注入用户信息)

    
    

        地址:待续

     
  • 相关阅读:
    03_ if 练习 _ little2big
    uva 11275 3D Triangles
    uva 12296 Pieces and Discs
    uvalive 3218 Find the Border
    uvalive 2797 Monster Trap
    uvalive 4992 Jungle Outpost
    uva 2218 Triathlon
    uvalive 3890 Most Distant Point from the Sea
    uvalive 4728 Squares
    uva 10256 The Great Divide
  • 原文地址:https://www.cnblogs.com/draymond/p/12499841.html
Copyright © 2011-2022 走看看