注解和反射知识点详细讲解

注解

什么是注解

在这里插入图片描述

内置注解

在这里插入图片描述

// 什么是内置注解
public class TestAnnotation extends Object{
    
    

    @Override
    public String toString() {
    
    
        return super.toString();
    }

    // 不推荐使用,但是可以使用,或者推荐更好的方式
    @Deprecated
    public static void test01() {
    
    
        System.out.println("this is a test");
    }

    @SuppressWarnings("all")
    public void test02() {
    
    
        List<String> list = new ArrayList<String>();
    }

    public static void main(String[] args) {
    
    
        test01();
    }
}

使用元注解自定义注解

在这里插入图片描述
在这里插入图片描述

// 测试元注解
public class TestAnnotation2 {
    
    

    @MyAnnotation
    public void test() {
    
    

    }

}

// 定义一个注解
// Target 表示注解可以放在什么上面
@Target(ElementType.METHOD)

// Retention 表示注解在什么地方还有效
// runtime > class > sources
@Retention(value = RetentionPolicy.RUNTIME)

// Documented 表示是否将我们的注解生成在JAVAdoc中
@Documented

// Inherited 子类可以继承父类的注解
@Inherited
@interface MyAnnotation {
    
    

}
-----------------------------------------------------------------------------
// 自定义注解
public class TestAnnotation3 {
    
    

    // 注解可以显示赋值,如果没有默认值,我们必须给注解赋值
    @MyAnnotation2(name = "张三", schools = {
    
    "天津大学", "清华大学"})
    public void test() {
    
    

    }

    @MyAnnotation3("张三")
    public void test01() {
    
    
        
    }
}

@Target({
    
    ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2 {
    
    

    // 注解的参数:参数类型 + 参数名 ();
    String name() default "";

    int age() default 0;

    int id() default -1; // 如果默认值为 -1,代表不存在

    String[] schools();
}

@Target({
    
    ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation3 {
    
    
    String value();
}

反射

动态语言和静态语言

在这里插入图片描述
在这里插入图片描述

反射的功能

在这里插入图片描述

// 反射的基本操作
public class TestReflection {
    
    
    public static void main(String[] args) throws ClassNotFoundException {
    
    
        // 通过反射获取类的Class对象
        Class c1 = Class.forName("com.yicheng.reflection.User");
        System.out.println(c1);

        // Class对象可以有哪些操作
        // 获取该类的所有注解
        c1.getAnnotations();
        // 获取该类的所有方法
        c1.getMethods();
        // 获取该类的所有字段
        c1.getFields();
        // 获取该类的所有构造方法
        c1.getConstructors();

        Class c2 = Class.forName("com.yicheng.reflection.User");
        Class c3 = Class.forName("com.yicheng.reflection.User");
        Class c4 = Class.forName("com.yicheng.reflection.User");
        // 一个类内存中只有一个 Class 对象
        // 一个类被加载后,类的整个结构都会被封装在 Class 对象中
        System.out.println("------------------");
        System.out.println(c2.hashCode());
        System.out.println(c3.hashCode());
        System.out.println(c4.hashCode());
    }
}

执行结果

class com.yicheng.reflection.User
------------------
1735600054
1735600054
1735600054

反射的优缺点

在这里插入图片描述

反射相关的主要 API

在这里插入图片描述

Class 类

在这里插入图片描述

哪些类型可以有 Class 对象

在这里插入图片描述

// 所有类型的Class
public class TestReflection3 {
    
    

    public static void main(String[] args) {
    
    
        Class c1 = Object.class; // 类
        Class c2 = Comparable.class; // 接口
        Class c3 = String[].class; // 一维数组
        Class c4 = int[][].class; // 二维数组
        Class c5 = Override.class; // 注解
        Class c6 = ElementType.class; // 枚举
        Class c7 = Integer.class; // 基本数据类型
        Class c8 = void.class; // void
        Class c9 = Class.class; // Class

        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);
        System.out.println(c4);
        System.out.println(c5);
        System.out.println(c6);
        System.out.println(c7);
        System.out.println(c8);
        System.out.println(c9);

        // 只要元素类型与维度一样要,就是同一个Class
        System.out.println("-----------------------------");
        int[] a = new int[10];
        int[] b = new int[100];
        System.out.println(a.getClass().hashCode());
        System.out.println(b.getClass().hashCode());
    }
}

执行结果

class java.lang.Object
interface java.lang.Comparable
class [Ljava.lang.String;
class [[I
interface java.lang.Override
class java.lang.annotation.ElementType
class java.lang.Integer
void
class java.lang.Class
-----------------------------
356573597
356573597

创建 Class 类的实例

在这里插入图片描述

// Class 类的创建方式有哪些
public class TestReflection02 {
    
    
    public static void main(String[] args) throws ClassNotFoundException {
    
    
        Person person = new Student();
        System.out.println("这个人是" + person.name);

        // 方式一:通过对象获得
        Class c1 = person.getClass();
        System.out.println("通过 person.getClass() 方式获得 Class 对象:" + c1.hashCode());

        // 方式二:forName获得
        Class c2 = Class.forName("com.yicheng.reflection.Student");
        System.out.println("通过 Class.forName() 方式获得 Class 对象:" + c2.hashCode());

        // 方式三:通过 类名.class 获得
        Class c3 = Student.class;
        System.out.println("通过 Student.class 方式获得 Class 对象:" + c3.hashCode());

        // 方式四:基本内置类型的包装类都有一个Type属性
        Class c4 = Integer.TYPE;
        System.out.println("基本内置类型通过 Integer.TYPE 方式获得 Class 对象:" + c4);

        // 获得父类类型
        Class c5 = c1.getSuperclass();
        System.out.println("通过 c1.getSuperclass() 方式获得父类 Class 对象:" + c5);
    }
}

class Person {
    
    
    public String name;

    public Person() {
    
    }

    public Person(String name) {
    
    
        this.name = name;
    }

    @Override
    public String toString() {
    
    
        return "Person{" + "name='" + name + '\'' + '}';
    }
}

class Student extends Person {
    
    
    public Student() {
    
    
        this.name = "学生";
    }
}

class Teacher extends Person {
    
    
    public Teacher() {
    
    
        this.name = "老师";
    }
}

执行结果

这个人是学生
通过 person.getClass() 方式获得 Class 对象:356573597
通过 Class.forName() 方式获得 Class 对象:356573597
通过 Student.class 方式获得 Class 对象:356573597
基本内置类型通过 Integer.TYPE 方式获得 Class 对象:int
通过 c1.getSuperclass() 方式获得父类 Class 对象:class com.yicheng.reflection.Person

Class 类的常用方法

在这里插入图片描述

// 获得类信息
public class TestClassInfo {
    
    

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
    
    
        Class c1 = Class.forName("com.yicheng.reflection.User");

        // 获得类的名字
        System.out.println("c1.getName() 获得的是包名 + 类名 " + c1.getName());
        System.out.println("c1.getSimpleName() 获得的是类名 " + c1.getSimpleName());

        // 获得类的属性
        System.out.println("-----------------------------");
        Field[] fields = c1.getFields(); // 只能找到public属性,因无public属性所以打印无结果
        fields = c1.getDeclaredFields();
        for (Field field : fields) {
    
    
            System.out.println("c1.getDeclaredFields() 获得的是全部属性 " + field);
        }

        // 获得指定属性的值
        System.out.println("-----------------------------");
        Field name = c1.getDeclaredField("name");
        System.out.println("c1.getDeclaredField() 获得的是指定属性 " + name);

        // 获得类的方法
        System.out.println("-----------------------------");
        Method[] methods = c1.getMethods();
        for (Method method : methods) {
    
    
            System.out.println("c1.getMethods() 获得本类及其父类的全部public方法 " + method);
        }
        System.out.println("-----------------------------");
        methods = c1.getDeclaredMethods(); // 获得本类所有的方法,包括 private 方法
        for (Method method : methods) {
    
    
            System.out.println("c1.getDeclaredMethods() 获得本类所有包括private在内的方法 " + method);
        }

        // 获得指定方法
        System.out.println("-----------------------------");
        Method getName = c1.getMethod("getName", null);
        System.out.println("c1.getMethod() 获得指定的方法 " + getName);
        Method setName = c1.getMethod("setName", String.class);
        System.out.println("c1.getMethod() 获得指定的方法 " + setName);

        // 获得类的构造器
        System.out.println("-----------------------------");
        Constructor[] constructors = c1.getConstructors();
        for (Constructor constructor : constructors) {
    
    
            System.out.println("c1.getConstructors() 获得public构造方法 " + constructor);
        }
        System.out.println("-----------------------------");
        constructors = c1.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
    
    
            System.out.println("c1.getDeclaredConstructors() 获得全部构造方法 " + constructor);
        }

        // 获得指定的构造器
        System.out.println("-----------------------------");
        Constructor declaredConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
        System.out.println("c1.getDeclaredConstructor() 获得指定的构造器 " + declaredConstructor);
    }
}

执行结果

c1.getName() 获得的是包名 + 类名 com.yicheng.reflection.User
c1.getSimpleName() 获得的是类名 User
-----------------------------
c1.getDeclaredFields() 获得的是全部属性 private java.lang.String com.yicheng.reflection.User.name
c1.getDeclaredFields() 获得的是全部属性 private int com.yicheng.reflection.User.id
c1.getDeclaredFields() 获得的是全部属性 private int com.yicheng.reflection.User.age
-----------------------------
c1.getDeclaredField() 获得的是指定属性 private java.lang.String com.yicheng.reflection.User.name
-----------------------------
c1.getMethods() 获得本类及其父类的全部public方法 public java.lang.String com.yicheng.reflection.User.toString()
c1.getMethods() 获得本类及其父类的全部public方法 public java.lang.String com.yicheng.reflection.User.getName()
c1.getMethods() 获得本类及其父类的全部public方法 public int com.yicheng.reflection.User.getId()
c1.getMethods() 获得本类及其父类的全部public方法 public void com.yicheng.reflection.User.setName(java.lang.String)
c1.getMethods() 获得本类及其父类的全部public方法 public void com.yicheng.reflection.User.setId(int)
c1.getMethods() 获得本类及其父类的全部public方法 public int com.yicheng.reflection.User.getAge()
c1.getMethods() 获得本类及其父类的全部public方法 public void com.yicheng.reflection.User.setAge(int)
c1.getMethods() 获得本类及其父类的全部public方法 public final void java.lang.Object.wait() throws java.lang.InterruptedException
c1.getMethods() 获得本类及其父类的全部public方法 public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
c1.getMethods() 获得本类及其父类的全部public方法 public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
c1.getMethods() 获得本类及其父类的全部public方法 public boolean java.lang.Object.equals(java.lang.Object)
c1.getMethods() 获得本类及其父类的全部public方法 public native int java.lang.Object.hashCode()
c1.getMethods() 获得本类及其父类的全部public方法 public final native java.lang.Class java.lang.Object.getClass()
c1.getMethods() 获得本类及其父类的全部public方法 public final native void java.lang.Object.notify()
c1.getMethods() 获得本类及其父类的全部public方法 public final native void java.lang.Object.notifyAll()
-----------------------------
c1.getDeclaredMethods() 获得本类所有包括private在内的方法 public java.lang.String com.yicheng.reflection.User.toString()
c1.getDeclaredMethods() 获得本类所有包括private在内的方法 public java.lang.String com.yicheng.reflection.User.getName()
c1.getDeclaredMethods() 获得本类所有包括private在内的方法 public int com.yicheng.reflection.User.getId()
c1.getDeclaredMethods() 获得本类所有包括private在内的方法 public void com.yicheng.reflection.User.setName(java.lang.String)
c1.getDeclaredMethods() 获得本类所有包括private在内的方法 public void com.yicheng.reflection.User.setId(int)
c1.getDeclaredMethods() 获得本类所有包括private在内的方法 public int com.yicheng.reflection.User.getAge()
c1.getDeclaredMethods() 获得本类所有包括private在内的方法 public void com.yicheng.reflection.User.setAge(int)
-----------------------------
c1.getMethod() 获得指定的方法 public java.lang.String com.yicheng.reflection.User.getName()
c1.getMethod() 获得指定的方法 public void com.yicheng.reflection.User.setName(java.lang.String)
-----------------------------
c1.getConstructors() 获得public构造方法 public com.yicheng.reflection.User()
c1.getConstructors() 获得public构造方法 public com.yicheng.reflection.User(java.lang.String,int,int)
-----------------------------
c1.getDeclaredConstructors() 获得全部构造方法 public com.yicheng.reflection.User()
c1.getDeclaredConstructors() 获得全部构造方法 public com.yicheng.reflection.User(java.lang.String,int,int)
-----------------------------
c1.getDeclaredConstructor() 获得指定的构造器 public com.yicheng.reflection.User(java.lang.String,int,int)

Java 内存分析

在这里插入图片描述
稍后会出内存分析专讲。

类的加载和初始化

在这里插入图片描述

// 类加载顺序
public class TestClassLoader2 {
    
    
    public static void main(String[] args) {
    
    
        Child child = new Child();
    }
}

class Parent {
    
    
    public static int i = 10;
    private int j = 15;

    static {
    
    
        System.out.println("parent 静态代码块,无静态变量");
    }

    static {
    
    
        i = i + 100;
        System.out.println("parent 静态代码块,有静态变量,i = " + i);
    }

    {
    
    
        System.out.println("parent 代码块,无静态变量");
    }

    {
    
    
        j = j + 200;
        System.out.println("parent 代码块,有静态变量,j = " + j);
    }

    public Parent() {
    
    
        System.out.println("parent 构造方法");
    }

}

class Child extends Parent {
    
    
    public static int m = 26;
    private int n = 37;

    static {
    
    
        System.out.println("child 静态代码块,无静态变量");
    }

    static {
    
    
        m = m + 300;
        System.out.println("child 静态代码块,有静态变量,m = " + m);
    }

    {
    
    
        System.out.println("child 代码块,无静态变量");
    }

    {
    
    
        n = n + 400;
        System.out.println("child 代码块,有静态变量, n = " + n);
    }

    public Child() {
    
    
        System.out.println("child 构造方法");
    }
}

执行结果

parent 静态代码块,无静态变量
parent 静态代码块,有静态变量,i = 110
child 静态代码块,无静态变量
child 静态代码块,有静态变量,m = 326
parent 代码块,无静态变量
parent 代码块,有静态变量,j = 215
parent 构造方法
child 代码块,无静态变量
child 代码块,有静态变量, n = 437
child 构造方法

加载顺序总结

  1. 若存在继承关系,而且父类和子类中都存在静态代码块、静态变量、构造代码块、构造方法

  2. 先是父类静态代码块和静态变量,静态代码块和静态变量的初始化顺序 是谁在前谁先加载

  3. 再是子类静态代码块和静态变量,静态代码块和静态变量的初始化顺序 是谁在前谁先加载

  4. 再是父类构造代码块,父类构造方法

  5. 再是子类构造代码块,父类构造方法

什么时候会发生类初始化

在这里插入图片描述
注意事项
在这里插入图片描述

Class 对象能做什么

创建类的对象

在这里插入图片描述

// Class 创建对象
public class TestCreateObj {
    
    
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException,
            InvocationTargetException, NoSuchFieldException {
    
    
        // 获得Class对象
        Class c1 = Class.forName("com.yicheng.reflection.User");

        // 构造一个对象
        User user = (User) c1.newInstance(); // 本质是调用了类的无参构造器,如果没有无参构造器,会报错
        System.out.println(user);

        // 通过构造器创建对象
        System.out.println("---------------------");
        Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
        User user2 = (User) constructor.newInstance("张三", 1, 18);
        System.out.println(user2);
    }
}

执行结果

User{name='null', id=0, age=0}
---------------------
User{name='张三', id=1, age=18}

更改指定的属性

可以通过 getDeclaredField() 方法获取指定的属性并进行相应的操作。

setAccessible() 方法的作用
在这里插入图片描述

// Class 操作属性
public class TestClassOperateField {
    
    
    public static void main(String[] args) throws IllegalAccessException, ClassNotFoundException, InstantiationException, NoSuchFieldException {
    
    
        // 获得Class对象
        Class c1 = Class.forName("com.yicheng.reflection.User");

        // 通过反射操作属性
        User user4 = (User) c1.newInstance();
        Field name = c1.getDeclaredField("name");
        // 不能直接操作私有属性,需要关打开修改权限,属性或者方法的 setAccessible(true)
        name.setAccessible(true);
        name.set(user4, "王二");
        System.out.println(user4);
    }
}

执行结果

User{name='王二', id=0, age=0}

调用指定的方法

在这里插入图片描述
在这里插入图片描述

// Class对象调用方法
public class TestClassOperateMethod {
    
    
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException,
            InvocationTargetException, NoSuchFieldException {
    
    
        // 获得Class对象
        Class c1 = Class.forName("com.yicheng.reflection.User");

        // 通过反射调用普通方法
        User user3 = (User) c1.newInstance();
        // 通过反射获取一个方法
        Method setName = c1.getDeclaredMethod("setName", String.class);
        // invoke:激活的意思  (对象, "方法的值")
        setName.invoke(user3, "李四");
        System.out.println(user3);
    }
}
User{name='李四', id=0, age=0}

获得注解以及注解值

// 反射操作注解
public class TestReflectionAnnotation {
    
    

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
    
    
        Class c1 = Class.forName("com.yicheng.reflection.Doctor");
        // 通过反射获得注解
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation : annotations) {
    
    
            System.out.println("通过 c1.getAnnotations() 方法获得所有的注解:" + annotation);
        }

        // 获得注解value的值
        System.out.println("----------------------------");
        TableBlue tableBlue = (TableBlue) c1.getAnnotation(TableBlue.class);
        String value = tableBlue.value();
        System.out.println("通过 c1.getAnnotation() 获取指定注解,再获取属性值:" + value);

        // 获得类的字段的注解
        System.out.println("----------------------------");
        Field name = c1.getDeclaredField("id");
        FidleBlue fidleBlue = name.getAnnotation(FidleBlue.class);
        System.out.println("通过 name.getAnnotation() 获取指定字段的注解:" + fidleBlue.columnName());
        System.out.println("通过 name.getAnnotation() 获取指定字段的注解:" + fidleBlue.length());
        System.out.println("通过 name.getAnnotation() 获取指定字段的注解:" + fidleBlue.type());
    }
}

@TableBlue("db_doctor")
class Doctor {
    
    
    @FidleBlue(columnName = "db_id", type = "int", length = 10)
    private int id;
    @FidleBlue(columnName = "db_name", type = "varchar", length = 10)
    private String name;
    @FidleBlue(columnName = "db_age", type = "int", length = 10)
    private int age;

    public Doctor() {
    
    }

    public Doctor(int id, String name, int age) {
    
    
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int getId() {
    
    
        return id;
    }

    public void setId(int id) {
    
    
        this.id = id;
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public int getAge() {
    
    
        return age;
    }

    public void setAge(int age) {
    
    
        this.age = age;
    }

    @Override
    public String toString() {
    
    
        return "Doctor{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}';
    }
}

// 类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface TableBlue {
    
    
    String value();
}

// 属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FidleBlue {
    
    
    String columnName();

    String type();

    int length();
}

执行结果

通过 c1.getAnnotations() 方法获得所有的注解:@com.yicheng.reflection.TableBlue(value=db_doctor)
----------------------------
通过 c1.getAnnotation() 获取指定注解,再获取属性值:db_doctor
----------------------------
通过 name.getAnnotation() 获取指定字段的注解:db_id
通过 name.getAnnotation() 获取指定字段的注解:10
通过 name.getAnnotation() 获取指定字段的注解:int

获得泛型

// 通过反射获取泛型
public class TestGeneric {
    
    
    public void test01(Map<Integer, User> map, List<User> list) {
    
    
        System.out.println("test01");
    }

    public Map<String, User> test02() {
    
    
        System.out.println("test02");
        return null;
    }

    public static void main(String[] args) throws NoSuchMethodException {
    
    

        // 参数泛型
        // 获取方法 test01
        Method method = TestGeneric.class.getMethod("test01", Map.class, List.class);
        // 找到该方法所有带泛型的参数
        Type[] genericParameterTypes = method.getGenericParameterTypes();
        for (Type genericParameterType : genericParameterTypes) {
    
    
            // 打印该参数的泛型所有泛型类型
            System.out.println("带泛型的参数:" + genericParameterType);
            if (genericParameterType instanceof ParameterizedType) {
    
    
                Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
                // 对该参数的所有泛型类型进行遍历
                for (Type actualTypeArgument : actualTypeArguments) {
    
    
                    System.out.println("参数的具体类型:" + actualTypeArgument);
                }
            }
        }

        // 返回值泛型
        System.out.println("------------------------------");
        Method method2 = TestGeneric.class.getMethod("test02", null);
        Type genericReturnType = method2.getGenericReturnType();
        System.out.println("带泛型的返回值:" + genericReturnType);
        if (genericReturnType instanceof ParameterizedType) {
    
    
            Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
    
    
                System.out.println("返回值的具体类型:" + actualTypeArgument);
            }
        }
    }
}

执行结果

带泛型的参数:java.util.Map<java.lang.Integer, com.yicheng.reflection.User>
参数的具体类型:class java.lang.Integer
参数的具体类型:class com.yicheng.reflection.User
带泛型的参数:java.util.List<com.yicheng.reflection.User>
参数的具体类型:class com.yicheng.reflection.User
------------------------------
带泛型的返回值:java.util.Map<java.lang.String, com.yicheng.reflection.User>
返回值的具体类型:class java.lang.String
返回值的具体类型:class com.yicheng.reflection.User

Class 调用方法效率测试

// 反射会费时,测试时间
public class TestSpeed {
    
    

    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
    
    
        test01();
        test02();
        test03();
    }

    // 普通方式调用
    public static void test01() {
    
    
        User user = new User();
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
    
    
            user.getName();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("普通方式执行10亿次:" + (endTime - startTime) + "ms");
    }

    // 反射方式调用
    public static void test02() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    
    
        User user = new User();
        Class c1 = user.getClass();
        Method getName = c1.getDeclaredMethod("getName", null);
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
    
    
            getName.invoke(user, null);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("反射方式执行10亿次:" + (endTime - startTime) + "ms");
    }

    // 反射方式调用 打开访问私有权限
    public static void test03() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    
    
        User user = new User();
        Class c1 = user.getClass();
        Method getName = c1.getDeclaredMethod("getName", null);
        getName.setAccessible(true);
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
    
    
            getName.invoke(user, null);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("反射方式打开权限执行10亿次:" + (endTime - startTime) + "ms");
    }
}

执行结果

普通方式执行10亿次:3ms
反射方式执行10亿次:1852ms
反射方式打开权限执行10亿次:1656ms

学习注解和反射之后,感觉二者的配合真的天衣无缝,如果您有新的想法,欢迎一起交流分享。

猜你喜欢

转载自blog.csdn.net/qq_42647711/article/details/109646470
今日推荐