• 反射 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+注解+反射  自动对数据库查询不到的值赋值

    
    

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

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

    
    

        地址:待续

     
  • 相关阅读:
    Java学习的第五十一天
    Java学习的第五十四天
    Java学习的第五十天
    Java学习的第五十三天
    Java学习的第五十二天
    Java学习的第四十九天
    构造函数
    封 装
    JAVA学习日报 10/8
    JAVA学习日报 10.11
  • 原文地址:https://www.cnblogs.com/draymond/p/12499841.html
Copyright © 2020-2023  润新知