一文详解Java反射


反射是什么?

反射就是:加载类,并允许以编程的方式解剖类中的某个成分(成员变量,方法,构造器等)
反射需要学什么

  1. 反射第一步:加载类,获取类的字节码:Class对象
  2. 获取类的构造器:Constructor对象
  3. 获取类的成员变量:Field对象
  4. 获取类的成员方法:Method对象

在反射中,最重要的就是Class对象,之后的一切操作都是根据Class对象来操作的

反射的作用

  • 基本作用:可以得到一个类的全部成分然后操作

  • 可以破坏封装性

  • 适合做Java的框架,主流的框架会基于反射设计出一些通用的功能

一下测试代码我只提供了一个方法,需要源代码的在这里:反射代码

所有方法汇总

在这里插入图片描述

一、加载Class对象

获取Class对象的三种方法

  • Class c1 = 类名.class
  • 调用Class提供方法:public static Class forName(String Package);
  • Object提供的方法:public Class getClass(); Class c3 = 对象.getClass();
    /**
     * 测试三种方式得到的Class的三种方法
     * @throws ClassNotFoundException
     */
    @Test
    public void testEquals() throws ClassNotFoundException {
        Class s1 = Class.forName("com.wk.reflect.Student");
        Class s2 = Student.class;
        Student student = new Student();
        Class s3 = student.getClass();
        System.out.println(s1 == s2);   //true
        System.out.println(s2 == s3);   //true
        System.out.println(s1 == s3);   //true
    }

二、加载类的构造器对象

加载构造器对象的步骤:

  • 获取类的Class对象
  • 调用方法获得构造器对象
  • 使用:创建一个对象实例newInstance()

获取构造器的方法如下

方法说明
Constructor<?>[] getConstructors()获取全部构造器(只能获取public修饰)
Constructor<?>[] getDeclaredConstructors()获取全部构造器(任意修饰都可以拿到)
Constructor getConstructor(Class<?>… parameterTypes)获取某个构造器(只能能获取public修饰)
Constructor getDeclaredConstructor(Class<?>… parameterTypes)获取某个构造器(任意修饰都可以拿到)
Constructor提供的方法说明
T newInstance(Object… initargs调用此构造器对象表示的构造器,并传入参数,完成对象的初始化并返回
public void setAccessible(boolean flag)设置为True,表示禁止加内存访问控制(暴力反射)
    @Test
    public void testAll() throws Exception {
        //获得一个Class对象
        Class<Student> s1 = Student.class;
        //获取一个构造器
        //这里将无参构造器设置为private的,但是这个也可以获取
        Constructor<Student> constructor = s1.getDeclaredConstructor();  
        //无参构造器是private的,所以需要暴力反射
        constructor.setAccessible(true);   
        Student stu = constructor.newInstance();
        System.out.println(stu);
    }
--------------输出---------------
无参构造器执行...
Student{age=0, name='null'}

三、加载类的成员变量

加载成员变量对象的步骤:

  • 获取类的Class对象
  • 调用方法获得成员变量对象
  • 使用:调用成员变量对象的get()/set()方法

获取构成员变量的方法如下

方法说明
public Field[] getFields()获取类的全部成员变量(只能获取public修饰的)
public Field[] getDeclaredFields()获取类的全部成员变量(任意修饰都可以拿到)
public Field getField(String name)获取类的某个成员变量(只能获取public修饰的)
public Field getDeclaredField(String name)获取类的某个成员变量(任意修饰都可以拿到)
方法说明
void set(Object obj, Object value);赋值
Object get(Object obj)取值
public void setAccessible(boolean flag)设置为true,表示禁止检查访问控制(暴力反射)
    @Test
    public void testAllField() throws Exception {
        Class<Student> student = Student.class;
        //单个时输入变量名
        Field age = student.getDeclaredField("age");

        Student student1 = new Student();
        age.setAccessible(true);
        age.set(student1,18);
        System.out.println(student1);
    }
------------输出--------------
无参构造器执行...
Student{age=18, name='null'}

四、加载类的成员方法

加载成员方法对象的步骤:

  • 获取类的Class对象
  • 调用方法获得成员方法对象
  • 使用:调用成员方法对象的invoke()方法
方法
Method[] getMethods()获取类的全部成员变量(只能获取public修饰的)
Method[] getDeclaredMethods()获取类的全部成员变量(任意修饰都可以拿到)
Method getMethod(String name, Class<?>… parameterTypes)获取类的某个成员变量(只能获取public修饰的)
Method getDeclaredMethod(String name, Class<?>… parameterTypes)获取类的某个成员变量(任意修饰都可以拿到)
Mehode提供的方法说明
public Object invoke(Object obj, Object… args)触发某个对象的该方法执行
public void setAccessible(boolean flag)设置为true,表示禁止检查访问控制(暴力反射)
    @Test
    public void testAllMethod() throws Exception {
        Class<Animal> animal = Animal.class;
        //参数为方法的名称
        Method declaredMethod = animal.getDeclaredMethod("eat");
        declaredMethod.setAccessible(true);
        Animal animal1 = new Animal();
        Object invoke = declaredMethod.invoke(animal1);
        //返回值为null
        System.out.println(invoke);
    }
-----------输出--------------
动物吃
null

完结~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无技术,不人生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值