• Java反射机制


    一、获取Class对象

        通过类对象获取

            person.getClass()

        通过类直接调用class获取

            Person.class

        通过Class.forName获取

            Class.forName("Person")

        通过类加载器获取

            this.getClass().getClassLoader().loadClass("Person")

        基本数据类型及包装类

            Integer.TYPE

            int.class

    二、Java反射API

        1、总结

            get系列:本类的public + 父类或接口的public(含静态方法)

    getDeclared系列:本类所有的访问权限的元素(含静态方法)

            修饰符-Modifier.toString(xx.getModifiers())

            名称-xx.getName()

            注解-xx.getDeclaredAnnotations()

            私有构造函数或方法调用前需加-xx.setAccessible(true);

        2、Class(类)

            包路径-getPackage()

                null

            注解-clazz.getDeclaredAnnotations()

                @java.lang.Deprecated()

            修饰符-Modifier.toString(clazz.getModifiers())

                public

            类名称-clazz.getName()

                Person

            类简单名称-clazz.getSimpleName()

                Person

            直属父类-clazz.getGenericSuperclass()

                class BasePerson

            直属接口-clazz.getGenericInterfaces()

                interface PersonInterface

        3、Constructor(构造函数)

            public构造函数-clazz.getConstructors()

                public Person()

            构造函数-clazz.getDeclaredConstructors()

                public Person()

                private Person(java.lang.String)

            指定构造函数-clazz.getDeclaredConstructor(String.class)

                private Person(java.lang.String)

            私有构造函数-constructor.setAccessible(true)

            实例化对象-constructor.newInstance("Linsa")

                Person(name=Linsa)

            注解-constructor.getDeclaredAnnotations()

                @java.lang.Deprecated()

            修饰符-Modifier.toString(constructor.getModifiers())

                private

            参数类型-constructor.getGenericParameterTypes()

                class java.lang.String

        4、Field(属性)

            public属性-clazz.getFields()

                public java.lang.String Person.name

                public int BasePerson.age

            属性-getDeclaredFields()

                private static java.lang.Long Person.num

                public java.lang.String Person.name

            指定属性-clazz.getDeclaredField("num")

                private static java.lang.Long Person.num

            注解-field.getDeclaredAnnotations()

                @java.lang.Deprecated()

            修饰符-Modifier.toString(field.getModifiers())

                private static

            属性类型-Class type = field.getType()

                class java.lang.Long

            属性类型-Type genericType = field.getGenericType()

                class java.lang.Long

            属性名称-field.getName()

                num

        5、Method(方法)

            public方法-clazz.getMethods()

                public java.lang.String Person.toString()

                public final void java.lang.Object.wait() throws java.lang.InterruptedException

                Object类其他public方法

            方法-clazz.getDeclaredMethods()

                public java.lang.String Person.toString()

                private int Person.test(java.lang.String,long)

            指定方法-clazz.getDeclaredMethod("test", String.class)

                private int Person.test(java.lang.String,long)

            调用方法-spring注解类推荐第一种

                (int) method.invoke(object, "Linsa", 28L)

                (int) method.invoke(clazz.newInstance(), "Linsa", 28L)

                (int) method.invoke(clazz.getConstructor().newInstance(), "Linsa", 28L)

            注解-method.getDeclaredAnnotations()

                @java.lang.Deprecated()

            修饰符-Modifier.toString(method.getModifiers())

                private

            返回值类型-Class returnType = method.getReturnType()

                int

            返回值类型-Type genericReturnType = method.getGenericReturnType()

                int

            方法名称-method.getName()

                test

            方法入参-method.getParameters()

                java.lang.String name

                long num

     


    代码示例如下:

    import java.lang.annotation.Annotation;
    import java.lang.reflect.*;
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Collectors;

    public class ReflexDemo {
        public static void main(String[] args) throws Exception {
            //get系列:本类的public + 父类或接口的public(含静态方法)
            //getDeclared系列:本类所有的访问权限的元素(含静态方法)
            ReflexDemo reflexDemo = new ReflexDemo();
            reflexDemo.testClassFor();
            reflexDemo.testClass();
            reflexDemo.testConstructor();
            reflexDemo.testField();
            reflexDemo.testMethod();
        }

        //获取Class对象
        public void testClassFor() {
            // 1.通过类实例获取
            Person person = new Person();
            Class clazz1 = person.getClass();
            System.out.println("01 - " + clazz1);

            // 2.通过类直接调用class获取
            Class clazz2 = Person.class;
            System.out.println("02 - " + clazz2);

            // 3.通过Class.forName获取
            Class clazz3 = null;
            try {
                clazz3 = Class.forName("test.reflex.Person");
            } catch (ClassNotFoundException e) {
                // 当找不到指定类时,会抛出此异常
                e.printStackTrace();
            }
            System.out.println("03 - " + clazz3);

            // 4.通过类加载器获取
            ClassLoader classLoader = this.getClass().getClassLoader();
            Class clazz4 = null;
            try {
                clazz4 = classLoader.loadClass("test.reflex.Person");
            } catch (ClassNotFoundException e) {
                // 当找不到指定类时,会抛出此异常
                e.printStackTrace();
            }
            System.out.println("04 - " + clazz4);

            // hashCode相等,说明这四种方式获取的是同一个实例
            System.out.println("05 - " + clazz1.hashCode());
            System.out.println("06 - " + clazz2.hashCode());
            System.out.println("07 - " + clazz3.hashCode());
            System.out.println("08 - " + clazz4.hashCode());

            Class clazz5 = Integer.TYPE;
            System.out.println("基本数据类型的包装类" + clazz5);
            Class clazz6 = int.class;
            System.out.println("基本数据类型" + clazz6);
        }

        //Java反射API-Class(类)
        public void testClass() throws Exception {
            System.out.println("Java反射API-Class(类)begin");
            Class clazz = Class.forName("test.reflex.Person");

            // 获取该类所在包路径
            Package aPackage = clazz.getPackage();
            System.out.println("01 - " + aPackage);

            // 获取该类上所有注解
            Annotation[] declaredAnnotations = clazz.getDeclaredAnnotations();
            for (Annotation temp : declaredAnnotations) {
                System.out.println("02 - " + temp);
            }

            // 获取类上的修饰符
            String modifier = Modifier.toString(clazz.getModifiers());
            System.out.println("03 - " + modifier);

            // 获取类名称
            String name = clazz.getName();
            System.out.println("04 - " + name);

            // 获取简单类名
            String simpleName = clazz.getSimpleName();
            System.out.println("05 - " + simpleName);

            // 获取直属超类
            Type genericSuperclass = clazz.getGenericSuperclass();
            System.out.println("06 - " + genericSuperclass);

            // 获取直属实现的接口
            Type[] genericInterfaces = clazz.getGenericInterfaces();
            for (Type temp : genericInterfaces) {
                System.out.println("07 - " + temp);
            }
        }

        //Java反射API-Constructor(构造函数)
        public void testConstructor() throws Exception {
            System.out.println("Java反射API-Constructor(构造函数)begin");
            Class clazz = Class.forName("test.reflex.Person");

            // 获取所有声明为 public 构造函数实例
            Constructor[] constructorArray1 = clazz.getConstructors();
            for (Constructor constructor : constructorArray1) {
                System.out.println("01 - " + constructor);
            }

            // 获取所有声明的构造函数实例
            Constructor[] constructorArray2 = clazz.getDeclaredConstructors();
            for (Constructor constructor : constructorArray2) {
                System.out.println("02 - " + constructor);
            }

            // 获取一个声明为 private 构造函数实例
            Constructor constructor = clazz.getDeclaredConstructor(String.class);
            System.out.println("03 - " + constructor);

            // 将构造函数的可访问标志设为 true 后,可以通过私有构造函数创建实例
            constructor.setAccessible(true);// public方法不用加这一行
            Object o = constructor.newInstance("Linsa");
            System.out.println("04 - " + o);

            // 获取该构造函数上的所有注解
            Annotation[] annotations = constructor.getDeclaredAnnotations();
            for (Annotation annotation : annotations) {
                System.out.println("05 - " + annotation);
            }

            // 获取构造函数上的修饰符
            String modifier = Modifier.toString(constructor.getModifiers());
            System.out.println("06 - " + modifier);

            // 获取该构造函数上的所有参数类型
            Type[] genericParameterTypes = constructor.getGenericParameterTypes();
            for (Type genericParameterType : genericParameterTypes) {
                System.out.println("07 - " + genericParameterType);
            }

            // 获取构造函数的名称
            String name = constructor.getName();
            System.out.println("08 - " + name);
        }

        //Java反射API-Field(属性)
        public void testField() throws Exception {
            System.out.println("Java反射API-Field(属性)begin");
            Class clazz = Class.forName("test.reflex.Person");

            // 获取该类及父类中所有声明为 public 的属性
            Field[] fieldArray1 = clazz.getFields();
            for (Field field : fieldArray1) {
                System.out.println("01 - " + field);
            }

            // 获取该类中所有声明的属性
            Field[] fieldArray2 = clazz.getDeclaredFields();
            for (Field field : fieldArray2) {
                System.out.println("02 - " + field);
            }

            // 获取一个该类中声明的属性
            Field field = clazz.getDeclaredField("num");
            System.out.println("03 - " + field);

            // 获取该属性上的所有注解
            Annotation[] declaredAnnotations = field.getDeclaredAnnotations();
            for (Annotation declaredAnnotation : declaredAnnotations) {
                System.out.println("04 - " + declaredAnnotation);
            }

            // 获取修饰符
            String modifier = Modifier.toString(field.getModifiers());
            System.out.println("05 - " + modifier);

            // 获取属性类型,返回类对象
            Class type = field.getType();
            System.out.println("06 - " + type);

            // 获取属性类型,返回Type对象
            Type genericType = field.getGenericType();
            System.out.println("07 - " + genericType);

            // 获取属性名称
            String name = field.getName();
            System.out.println("08 - " + name);
        }

        //Java反射API-Method(方法)
        public void testMethod() throws Exception {
            System.out.println("Java反射API-Method(方法)begin");
            Class clazz = Class.forName("test.reflex.Person");

            // 获取该类及父类中所有声明为 public 的方法
            Method[] methods = clazz.getMethods();
            for (Method temp : methods) {
                System.out.println("01 - " + temp);
            }

            // 获取所有在该类中声明的方法
            Method[] declaredMethods = clazz.getDeclaredMethods();
            for (Method temp : declaredMethods) {
                System.out.println("02 - " + temp);
            }

            // 获取一个该类及父类中声明为 public 的方法,需要指定方法的入参类型
            Method method = clazz.getDeclaredMethod("test", String.class, long.class);
            System.out.println("03 - " + method);

            //调用该方法
            Object object = new Person();
            method.setAccessible(true);
            //Class.newInstance() 只能够调用无参的构造函数,即默认的构造函数;
            //Constructor.newInstance() 可以根据传入的参数,调用任意构造函数。
            int number = (int) method.invoke(object, "Linsa", 28L);
            number = (int) method.invoke(clazz.newInstance(), "Linsa", 28L);
            number = (int) method.invoke(clazz.getConstructor().newInstance(), "Linsa", 28L);
            System.out.println("04 - " + number);

            List list = Arrays.stream(clazz.getDeclaredMethods())
                    .filter(methodTemp -> "test1".equals(methodTemp.getName()))
                    .map(Method::getName)
                    .collect(Collectors.toList());
            System.out.println(list);

            // 获取该方法上的所有注解
            Annotation[] declaredAnnotations = method.getDeclaredAnnotations();
            for (Annotation temp : declaredAnnotations) {
                System.out.println("05 - " + temp);
            }

            // 获取修饰符
            String modifier = Modifier.toString(method.getModifiers());
            System.out.println("06 - " + modifier);

            // 获取返回值类型,返回类对象
            Class returnType = method.getReturnType();
            System.out.println("07 - " + returnType);

            // 获取返回值类型,返回Type对象
            Type genericReturnType = method.getGenericReturnType();
            System.out.println("08 - " + genericReturnType);

            // 获取方法名称
            String name = method.getName();
            System.out.println("09 - " + name);

            // 获取所有入参
            Parameter[] parameters = method.getParameters();
            for (Parameter temp : parameters) {
                System.out.println("10 - " + temp);
            }
        }
    }

    import lombok.NoArgsConstructor;
    import lombok.ToString;

    /**
     * 人实体类
     *
     * @author Linsa
     * @since 2022-08-04
     */
    @NoArgsConstructor
    @ToString
    @Deprecated
    public class Person extends BasePerson implements PersonInterface {
        @Deprecated
        private Person(String name) {
            this.name = name;
        }

        @Deprecated
        private static Long num;
        public String name;

        @Deprecated
        private int test(String name, long num){
            return 3;
        }
    }

    public class BasePerson {
        public int age;
    }

    public interface PersonInterface {
    }

  • 相关阅读:
    蓝牙Mesh专有DFU
    【MySQL】索引&事务
    3、CSS动态时钟
    Springboot零星知识点1
    2023数维杯国际赛数学建模D题完整论文分享!
    docker搭建drone
    2022年8月的工作经历
    Tomcat 架构
    Mybatis-Plus关于MYSQL中JSON字段的操作
    Java#31(不可变集合,Stream流和方法引用)
  • 原文地址:https://blog.csdn.net/linsa_pursuer/article/details/126184499