Java反射

106 阅读4分钟
package com.xiaofeng.test.reflectTest;

@Data
public class TestPerson {

    public TestPerson() {
    }
    
    public TestPerson(String name, String age, String mobile) {
        this.name = name;
        this.age = age;
        this.mobile = mobile;
    }
    
    private String name;
    private String age;
    private String mobile;
}

public class MyTest {
    public static void main(String[] args) throws Exception {

        /**
         * 一、获取目标类型的Class对象(个人理解叫类对象,注意和类的对象的区分)
         * java.lang.Class
         * 定义:类是反射机制的基础
         * 作用:存放着对应类型对象的 运行时信息
         */
        Class c1 = "JiaGouShi".getClass();
        Class c2 = Class.forName("java.lang.String");
        //用 == 来比较两个类对象的地址的比较
        System.out.println(c1 == c2);
        //输出结果:true,每种类型的Class对象只有一个 = 地址只有一个

        //获取 目标类型的`Class`对象 方式主要有三种
        //1,Object.getClass()
        TestPerson myTest = new TestPerson();
        Class<?> classType1 = myTest.getClass();
        System.out.println(classType1);

        //2,T.class 语法
        Class<?> classType2 = TestPerson.class;
        System.out.println(classType2);
        //注:Class对象表示的是一个类型,而这个类型未必一定是类
        //如:int不是类,但int.class是一个Class类型的对象

        //3,static method Class.forName
        Class<?> classType3 = Class.forName("com.xiaofeng.test.reflectTest.TestPerson");
        System.out.println(classType3);

        /**
         * 二、通过Class对象分别获取Constructor类对象,Method类对象,Field类对象
         */
        //1,获取类的构造函数
            //获取指定的构造函数 (公共/继承)
            //Constructor<T>  getConstructor(Class<?>... parameterTypes)

            //获取所有的构造函数 (公共/继承)
            //Constructor<?>[] getConstructors()

            //获取指定的构造函数 (不包括继承)
            //declared :已声明的,声明的
            //Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)


            //获取所有的构造函数 (不包括继承)
            //Constructor<?>[] getDeclaredConstructors()

        //特别注意:
            //a,不带'Declared'的方法支持取出包括 继承、公有(Public) & 不包括私有(private)的构造函数
            //b,带'Declared'的方法是支持取出包括 公有(Public)、保护(Protected)、默认(包)访问和私有(private)的构造函数,但不包括继承的构造函数。
            //下面同理

        //2,获取类的属性名
            //获取指定的属性 (公共/继承)
            //Field getField(String name)

            //获取所有的属性 (公共/继承)
            //Field[] getFields()

            //获取指定的属性 (不包括继承)
            //Field getDeclaredField(String name)

            //获取所有的属性 (不包括继承)
            //Field[] getDeclaredFields()

        //3,获取类的方法
            //获取所有的方法(公共 / 继承)
            //Method[] getMethods()

            //获取指定的方法(公共 / 继承)
            //Method getMethod(String name, Class<?>... parameterTypes)

            //获取所有的方法( 不包括继承)
            //Method[] getDeclaredMethods()

            //获取指定的方法 ( 不包括继承)
            //Method getDeclaredMethod(String name, Class<?>... parameterTypes)

        //4,Class类的其他方法
            //Class<? super T> getSuperclass() --返回父类
            //String getName() --返回完整的类名(含包名,如com.xiaofeng.test.reflectTest.TestPerson)
            //newInstance()
                // --快速地创建一个类的实例
                // 具体过程:调用默认构造器(若该类无默认构造器,则抛出异常)
                // 若想要为构造器提供参数,则需要调用java.lang.reflect.Constructor中的newInstance(Object ... initargs)

        /**
         * 三,通过Constructor类对象、Method类对象、Field类对象分别获取类的构造函数、方法、属性的具体信息
         */
        //1,通过Constructor类对象获取类构造函数信息
            //String getName() 获取构造器名
            //Class<T> getDeclaringClass() 获取一个用于描述类中定义的构造器的Class对象
            //int getModifiers() 返回整型数值,用不同的位开关描述访问修饰符的使用状况
            //Class<?>[] getExceptionTypes() 获取描述方法抛出的异常类型的Class对象数组
            //Class<?>[] getParameterTypes() 获取一个用于描述参数类型的Class对象数组
        //2,通过Field类对象获取类属性信息
            //String getName() 返回属性的名称
            //Class<?> getDeclaringClass() 获取方法的Class对象
            //Class<?> getType() 获取属性类型的Class类型对象
            //int getModifiers() 返回整型数值,用不同的位开关描述访问修饰符的使用状况
            //Object get(Object obj) 返回指定对象上 此属性的值
            //set(Object obj, Object value) 设置 指定对象上此属性的值为value
        //3,通过Method 类对象获取类方法信息
            //String getName() 获取方法名
            //Class<?> getDeclaringClass() 获取方法的Class对象
            //int getModifiers() 返回整型数值,用不同的位开关描述访问修饰符的使用状况
            //Class<?>[] getExceptionTypes() 获取描述方法抛出的异常类型的Class对象数组
            //Class<?>[] getParameterTypes() 获取一个用于描述参数类型的Class对象数组
        //4,java.lang.reflect.Modifier 获取访问修饰符
            //static String toString(int mod) 获取对应mod位设置的修饰符的字符串表示
            //isXXX(int mod) 检测方法名中对应的修饰符在mod中的值

        /**
         * 四,访问权限问题
         * 背景
         *      反射机制的默认行为受限于Java的访问控制
         *      如,无法访问( private )私有的方法、字段
         * 冲突
         *      Java安全机制只允许查看任意对象有哪些域,而不允许读它们的值
         *      --若强制读取,将抛出异常
         * 解决方案
         *      脱离Java程序中安全管理器的控制、屏蔽Java语言的访问检查,从而脱离访问控制
         *      具体实现手段:使用Field类、Method类 & Constructor类对象的setAccessible()
         */
        //void setAccessible(boolean flag)
        // 作用:为反射对象设置可访问标志
        // 规则:flag = true时 ,表示已屏蔽Java语言的访问检查,使得可以访问 & 修改对象的私有属性

        //boolean isAccessible()
        // 返回反射对象的可访问标志的值

    }
}