java_反射

本文详细介绍了Java反射机制,包括获取Class对象的三种方式、构造方法、成员变量和成员方法的反射操作,以及如何使用反射进行暴力访问。通过示例代码展示了反射在实际编程中的应用,如动态创建对象、调用私有方法等。此外,还讨论了暴力反射的概念及其在解决私有成员访问问题上的作用。
摘要由CSDN通过智能技术生成

目录

一、反射的概述

1.什么是反射

2.反射的好处

二、如何获取Class对象

1.三种方式

2.代码示例

三、反射获取构造方法

1.方法分类

2.Constructor类中创建对象的方法

3.代码示例 

四、反射获取成员变量

1.方法分类

2.Field类中成员变量赋值的方法

3.代码示例

五、反射获取成员方法

1.方法分类

2.Method类中执行方法的方法

3.代码示例

六、暴力反射

1.概述

2.暴力反射解决的问题

3.暴力反射的使用

七、创作不易恳求一键三连啦!!


一、反射的概述

1.什么是反射

        是指在运行时去获取一个类的变量和方法信息。然后通过获取到的信息来创建对象,调用方法的一种机制。

2.反射的好处

        由于反射这种动态性,可以极大的增强程序的灵活性,程序不用在编译期就完成确定,在运行期仍然可以扩展

二、如何获取Class对象

1.三种方式

  • 类名.class属性

  • 对象名.getClass()方法

  • Class.forName(全类名)方法

2.代码示例

public class ReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException {
        //使用类的class属性来获取该类对应的Class对象
        Class<Student> c1 = Student.class;
        System.out.println(c1);

        Class<Student> c2 = Student.class;
        System.out.println(c1 == c2);
        System.out.println("--------");

        //调用对象的getClass()方法,返回该对象所属类对应的Class对象
        Student s = new Student();
        Class<? extends Student> c3 = s.getClass();
        System.out.println(c1 == c3);
        System.out.println("--------");

        //使用Class类中的静态方法forName(String className)
        Class<?> c4 = Class.forName("com.itheima_02.Student");
        System.out.println(c1 == c4);
    }
}

三、反射获取构造方法

1.方法分类

方法名说明
Constructor<?>[] getConstructors()返回所有公共构造方法对象的数组
Constructor<?>[] getDeclaredConstructors()返回所有构造方法对象的数组
Constructor<T> getConstructor(Class<?>... parameterTypes)返回单个公共构造方法对象
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)返回单个构造方法对象

2.Constructor类中创建对象的方法

方法名说明
T newInstance(Object...initargs)根据指定的构造方法创建对象

3.代码示例 

public class ReflectDemo01 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取Class对象
        Class<?> c = Class.forName("com.itheima_02.Student");

        //Constructor<?>[] getConstructors() 返回一个包含 Constructor对象的数组, Constructor对象反映了由该 Class对象表示的类的所有公共构造函数
//        Constructor<?>[] cons = c.getConstructors();
        //Constructor<?>[] getDeclaredConstructors() 返回反映由该 Class对象表示的类声明的所有构造函数的 Constructor对象的数组
        Constructor<?>[] cons = c.getDeclaredConstructors();
        for(Constructor con : cons) {
            System.out.println(con);
        }
        System.out.println("--------");

        //Constructor<T> getConstructor(Class<?>... parameterTypes) 返回一个 Constructor对象,该对象反映由该 Class对象表示的类的指定公共构造函数
        //Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 返回一个 Constructor对象,该对象反映由此 Class对象表示的类或接口的指定构造函数
        //参数:你要获取的构造方法的参数的个数和数据类型对应的字节码文件对象

        Constructor<?> con = c.getConstructor();

        //Constructor提供了一个类的单个构造函数的信息和访问权限
        //T newInstance(Object... initargs) 使用由此 Constructor对象表示的构造函数,使用指定的初始化参数来创建和初始化构造函数的声明类的新实例
        Object obj = con.newInstance();
        System.out.println(obj);

//        Student s = new Student();
//        System.out.println(s);
    }
}

四、反射获取成员变量

1.方法分类

方法名说明
Field[] getFields()返回所有公共成员变量对象的数组
Field[] getDeclaredFields()返回所有成员变量对象的数组
Field getField(String name)返回单个公共成员变量对象
Field getDeclaredField(String name)返回单个成员变量对象

2.Field类中成员变量赋值的方法

方法名说明
voidset(Object obj,Object value)给obj对象的成员变量赋值为value

3.代码示例

public class ReflectDemo01 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取Class对象
        Class<?> c = Class.forName("com.itheima_02.Student");

        //Field[] getFields() 返回一个包含 Field对象的数组, Field对象反映由该 Class对象表示的类或接口的所有可访问的公共字段
        //Field[] getDeclaredFields() 返回一个 Field对象的数组,反映了由该 Class对象表示的类或接口声明的所有字段
//        Field[] fields = c.getFields();
        Field[] fields = c.getDeclaredFields();
        for(Field field : fields) {
            System.out.println(field);
        }
        System.out.println("--------");

        //Field getField(String name) 返回一个 Field对象,该对象反映由该 Class对象表示的类或接口的指定公共成员字段
        //Field getDeclaredField(String name) 返回一个 Field对象,该对象反映由该 Class对象表示的类或接口的指定声明字段
        Field addressField = c.getField("address");

        //获取无参构造方法创建对象
        Constructor<?> con = c.getConstructor();
        Object obj = con.newInstance();

//        obj.addressField = "西安";

        //Field提供有关类或接口的单个字段的信息和动态访问
        //void set(Object obj, Object value) 将指定的对象参数中由此 Field对象表示的字段设置为指定的新值
        addressField.set(obj,"西安"); //给obj的成员变量addressField赋值为西安

        System.out.println(obj);



//        Student s = new Student();
//        s.address = "西安";
//        System.out.println(s);
    }
}

五、反射获取成员方法

1.方法分类

方法名说明
Method[] getMethods()返回所有公共成员方法对象的数组,包括继承的
Method[] getDeclaredMethods()返回所有成员方法对象的数组,不包括继承的
Method getMethod(String name, Class<?>... parameterTypes)返回单个公共成员方法对象
Method getDeclaredMethod(String name, Class<?>... parameterTypes)返回单个成员方法对象

2.Method类中执行方法的方法

方法名说明
Objectinvoke(Object obj,Object... args)调用obj对象的成员方法,参数是args,返回值是Object类型

3.代码示例

public class ReflectDemo02 {
    public static void main(String[] args) throws Exception {
        //获取Class对象
        Class<?> c = Class.forName("com.itheima_02.Student");

        //Student s = new Student();
        Constructor<?> con = c.getConstructor();
        Object obj = con.newInstance();

        //s.method1();
        Method m1 = c.getMethod("method1");
        m1.invoke(obj);

        //s.method2("林青霞");
        Method m2 = c.getMethod("method2", String.class);
        m2.invoke(obj,"林青霞");

//        String ss = s.method3("林青霞",30);
//        System.out.println(ss);
        Method m3 = c.getMethod("method3", String.class, int.class);
        Object o = m3.invoke(obj, "林青霞", 30);
        System.out.println(o);

        //s.function();
//        Method m4 = c.getMethod("function"); //NoSuchMethodException: com.itheima_02.Student.function()
        Method m4 = c.getDeclaredMethod("function");
        m4.setAccessible(true);
        m4.invoke(obj);
    }
}

六、暴力反射

1.概述

        反射中强制使用得到的私有成员(构造方法、成员变量、成员方法)

2.暴力反射解决的问题

        虽然Class类中有方法可以得到私有的构造方法,但使用该私有构造方法创建对象会抛出异     常(IllegalAccessException)(异常访问异常)。因为按照常理私有构造方法是无法创建对象的。

3.暴力反射的使用

        反射中各成员(构造方法、成员变量、成员方法)所属类都有setAccessible(boolean flag)方法值为true时,取消访问检查。

如何使用
        反射中执行私有成员(构造方法、成员变量、成员方法)前,使用setAccessible(boolean flag)方法声明取消检查即可

七、创作不易恳求一键三连啦!!

  • 9
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值