• 注解和反射


    注解和反射

    注解

    注解和注释的区别

    注解 annotation写在程序之中,程序可以识别,做出相应的动作处理,具有检查和约束程序的作用

    注释 comment 写在程序之中,供人参考,提示使用,程序会自动忽略

    注解在JDK5开始引入

    常见注解

    @Override 重写一个方法

    @Deprecated 不推荐使用

    @SuppressWarnings("all") 镇压警告

    元注解

    元注解就是可以负责注解其他的注解

    @Target 描述注解的使用范围

    @Retention 表示在什么级别保存该注解信息(Source < Class < Runtime)

    @Document 该注解被包含在javadoc

    @Inherited 说明子类可以继承父类中的注解

    自定义注解

    @MyAnnotation(value = "User MyAnnotation", university = "家里蹲大学", age = 666)
    public class User {
        @MyAnnotation(name = "main Method", age = 18, id = 1, university = "复旦大学", value = "main MyAnnotation")
        public static void main(String[] args) throws NoSuchMethodException {
            Class<User> userClass = User.class;
            System.out.println("==============method===============");
            Method main = userClass.getMethod("main", String[].class);
            if (main.isAnnotationPresent(MyAnnotation.class)) {
                MyAnnotation annotation = main.getAnnotation(MyAnnotation.class);
                System.out.println(annotation.age());
                System.out.println(annotation.id());
                System.out.println(Arrays.toString(annotation.university()));
                System.out.println(annotation.name());
                System.out.println(annotation.value());
            }
            System.out.println("==============class===============");
            if (userClass.isAnnotationPresent(MyAnnotation.class)) {
                MyAnnotation annotation = userClass.getAnnotation(MyAnnotation.class);
                System.out.println(annotation.age());
                System.out.println(annotation.id());
                System.out.println(Arrays.toString(annotation.university()));
                System.out.println(annotation.name());
                System.out.println(annotation.value());
            }
        }
    }
    
    @Target(value = {ElementType.METHOD, ElementType.TYPE})
    @Retention(value = RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @interface MyAnnotation {
        String name() default "name";
    
        int age() default 0;
    
        // -1 代表不存在
        int id() default -1;
    
        String[] university() default {"清华大学", "北京大学"};
    
        String value();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    运行结果
    在这里插入图片描述

    注解级别

    @Table("Anno类")
    public class Anno {
        @Feild("用户名")
        private String username;
        @Method("main函数")
        public static void main(String[] args) {}
    }
    
    @Target(value = ElementType.TYPE)
    @Retention(value = RetentionPolicy.RUNTIME)
    @interface Table{
        String value();
    }
    
    @Target(value = ElementType.FIELD)
    @Retention(value = RetentionPolicy.RUNTIME)
    @interface Feild{
        String value();
    }
    
    @Target(value = ElementType.METHOD)
    @Retention(value = RetentionPolicy.RUNTIME)
    @interface Method{
        String value();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    查看ElementType枚举类的源码如下

    package java.lang.annotation;
    public enum ElementType{
        TYPE,
        FIELD,
        METHOD,
        PARAMETER,
        CONSTRUCTOR,
        LOCAL_VARIABLE,
        ANNOTATION_TYPE,
        PACKAGE,
        TYPE_PARAMETER,
        TYPE_USE,
        MODULE;
    
        private ElementType() {
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    这个枚举类实现了单例模式,构造器私有

    属性

    TYPE
    public static final ElementType TYPE
    类,接口(包括注释类型)或枚举声明

    FIELD
    public static final ElementType FIELD
    字段声明(包括枚举常数)

    METHOD
    public static final ElementType METHOD
    方法声明

    PARAMETER
    public static final ElementType PARAMETER
    正式参数声明

    CONSTRUCTOR
    public static final ElementType CONSTRUCTOR
    构造函数声明

    LOCAL_VARIABLE
    public static final ElementType LOCAL_VARIABLE
    局部变量声明

    ANNOTATION_TYPE
    public static final ElementType ANNOTATION_TYPE
    注解类型声明

    PACKAGE
    public static final ElementType PACKAGE
    包装声明

    TYPE_PARAMETER
    public static final ElementType TYPE_PARAMETER
    键入参数声明

    TYPE_USE
    public static final ElementType TYPE_USE
    使用类型

    MODULE
    public static final ElementType MODULE
    模块声明,jdk11具有的

    反射

    反射 reflection,一个类在内存中只存在一个class对象,一个类被加载之后,类的整个结构都会封装在Class对象中

    public class ReflectionDemo {
        public static void main(String[] args) throws ClassNotFoundException {
            Class<?> aClass = Class.forName("com.mao.pojo.User");
            Class<?> bClass = Class.forName("com.mao.pojo.User");
            Class<?> cClass = Class.forName("com.mao.pojo.User");
    
            System.out.println(aClass.hashCode());
            System.out.println(bClass.hashCode());
            System.out.println(cClass.hashCode());
        }
    }
    
    class User{
        private String username;
        private String password;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    获取class对象

        public static void main(String[] args) throws ClassNotFoundException {
            User user = new User();
            System.out.println(user);
    
            // 对象获取
            Class aClass = user.getClass();
            System.out.println(aClass.hashCode());
    
            // forName 获取
            Class bClass = Class.forName("com.mao.pojo.User");
            System.out.println(bClass.hashCode());
    
            // 类.class
            Class<User> cClass = User.class;
            System.out.println(cClass.hashCode());
    
            // 基本数据类型的包装类获得
            Class<Integer> type = Integer.TYPE;
            System.out.println(type);
    
            System.out.println(type.getSuperclass());
            System.out.println(aClass.getSuperclass());
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    所有类型的Class对象

        public static void main(String[] args) throws ClassNotFoundException {
            System.out.println(Object.class);
            System.out.println(Comparable.class);
            System.out.println(String[].class);
            System.out.println(int[][].class);
            System.out.println(Override.class);
            System.out.println(Integer.class);
            System.out.println(void.class);
            System.out.println(Class.class);
            System.out.println(new int[10].getClass().hashCode());
            System.out.println(new int[100].getClass().hashCode());
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    结果是

    class java.lang.Object
    interface java.lang.Comparable
    class [Ljava.lang.String;
    class [[I
    interface java.lang.Override
    class java.lang.Integer
    void
    class java.lang.Class
    750044075
    750044075

    查看类加载器

        public static void main(String[] args) throws ClassNotFoundException {
            ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
            System.out.println(systemClassLoader);
    
            ClassLoader parent = systemClassLoader.getParent();
            System.out.println(parent);
    
            ClassLoader parent1 = parent.getParent();
            System.out.println(parent1);
    
            ClassLoader classLoader = Class.forName("java.lang.Object").getClassLoader();
            System.out.println(classLoader);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    jdk.internal.loader.ClassLoaders A p p C l a s s L o a d e r @ 2437 c 6 d c j d k . i n t e r n a l . l o a d e r . C l a s s L o a d e r s AppClassLoader@2437c6dc jdk.internal.loader.ClassLoaders AppClassLoader@2437c6dcjdk.internal.loader.ClassLoadersPlatformClassLoader@2cb4c3ab
    null
    null

    在这里插入图片描述
    获取java运行放入环境在这里插入图片描述

    获取类运行时的结构

    public class ReflectionDemo {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
            Class className = Class.forName("com.mao.pojo.User");
            System.out.println(className.getClass());
            System.out.println(className.getSimpleName());
            System.out.println("=============================");
            User user = new User();
            className = user.getClass();
            System.out.println(className.getClass());
            System.out.println(className.getSimpleName());
            System.out.println(className.getField("username"));
            System.out.println(className.getField("password"));
        }
    }
    
    class User{
        public String username;
        private String password;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在这里插入图片描述
    获取构造器

            Class className = Class.forName("com.mao.pojo.User");
            Constructor[] constructors = className.getConstructors();
            for (Constructor constructor : constructors) {
                System.out.println(constructor);
            }
            constructors = className.getDeclaredConstructors();
            for (Constructor constructor : constructors) {
                System.out.println(constructor);
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    通过构造器创建对象

            Class classObject = Class.forName("com.mao.pojo.User");
            //  newInstance() 需要无参构造器,且防蚊权限足够
            User user = (User) classObject.newInstance();
            System.out.println(user);
    
            Constructor constructor = classObject.getDeclaredConstructor(String.class,String.class);
            User root = (User)constructor.newInstance("root", "123456");
            System.out.println(root);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    反射获取到类对象,创建实例,获取到方法的set方法,通过invoke激活,对对对象设置值

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InstantiationException, InvocationTargetException {
            Class classObject = Class.forName("com.mao.pojo.User");
            User user = (User) classObject.newInstance();
            Method setUsername = classObject.getDeclaredMethod("setUsername", String.class);
            setUsername.invoke(user,"root");
            System.out.println(user.getUsername());
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    反射将私有属性进行访问

            Class classObject = Class.forName("com.mao.pojo.User");
            User user = (User) classObject.newInstance();
            Field username = classObject.getDeclaredField("username");
            // 破解 private,取消安全检测
            username.setAccessible(true);
    
            username.set(user,"admin");
            System.out.println(user.getUsername());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    对比正常使用创建对象,反射创建对象,设置可见性的方式对比性能,结果发现new方式创建对象的方式最快,反射创建对象的时间最长,关闭检查,性能可提高一倍

    public class ReflectionDemo {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InstantiationException, InvocationTargetException {
            // 普通方式
            User user = new User();
            long start = System.currentTimeMillis();
            for (int i = 0; i < 1000000000; i++) {
                user.getUsername();
            }
            long end = System.currentTimeMillis();
            System.out.println(end - start);
    
            // 反射获取方法
            Class aClass = Class.forName("com.mao.pojo.User");
            Method getUsername = aClass.getDeclaredMethod("getUsername", null);
    
            long start1 = System.currentTimeMillis();
            for (int i = 0; i < 1000000000; i++) {
                getUsername.invoke(user,null);
            }
            long end1 = System.currentTimeMillis();
            System.out.println(end1 - start1);
    
    
            // 反射获取方法,关闭检查
            Class bClass = Class.forName("com.mao.pojo.User");
            Method getUsername1 = bClass.getDeclaredMethod("getUsername", null);
            getUsername1.setAccessible(true);
    
            long start2 = System.currentTimeMillis();
            for (int i = 0; i < 1000000000; i++) {
                getUsername1.invoke(user,null);
            }
            long end2 = System.currentTimeMillis();
            System.out.println(end2 - start2);
        }
    }
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    class User{
        private String username;
        private String password;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    在这里插入图片描述

  • 相关阅读:
    【HTML】通过焦点,获取部分上下文内容
    9 个对初学者开发者有价值的 GitHub 库✨
    SpringBoot之:SpringBoot的HATEOAS基础
    公共关系学知识点整理
    Servlet概述及接口
    数据赋能(102)——概念:数据分析、数据挖掘、数据洞察
    maven 包管理平台-05-multi module 多模块
    Web进阶
    亚马逊频繁扫号下的跨境电商,跨境电商卖家应该何去何从?
    spring initializr脚手架搭建详解
  • 原文地址:https://blog.csdn.net/qq_46724069/article/details/127837909