【java】反射机制

一、什么是反射机制
  • 1.将类的各个组成部分封装为其他对象
二、反射的优点
  • 1.可以在程序运行的过程中操作对象
  • 2.可以解耦,提高程序的可扩展性
三、获取Class对象的方式

说明: 同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个

3.1 Class.forName(全类名)
  • 1.将字节码文件加载进内存,返回Class对象
  • 2.多用于配置文件,将类名定义在配置文件中,读取文件,加载类
3.2 通过类名的class属性
  • 1. 类名.class
  • 2. 多用于参数的传递
3.3 对象.getClass()
  • 1. getClass()方法在Object类中定义的
  • 2. 多用于对象的获取字节码的方式
四、Class对象功能
4.1 获取功能
  • 1.获取成员变量
// 获取所有公开的成员变量,包括继承变量
Field[] fields = clazz.getFields();
// 获取本类定义的成员变量,包括私有,但不包括继承的变量
Field[] declaredFields = clazz.getDeclaredFields();
// 获取指定变量
Field field = clazz.getField("name");
Field declaredField = clazz.getDeclaredField("name");
  • 2.获取构造方法
//获取公开的构造方法
Constructor<?> constructor = clazz.getConstructor(String.class);
//获取所有的公开的构造方法
Constructor<?>[] constructors = clazz.getConstructors();
//获取所有的构造方法,包括私有
Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
Constructor<?> declaredConstructor = clazz.getDeclaredConstructor(int.class, String.class);
  • 3.获取成员方法
//获取所有可见的方法,包括继承的方法
Method[] methods = clazz.getMethods();
//获取本类定义的的方法
Method test = clazz.getMethod("test", String.class);
//获取本类定义的的方法,包括私有,不包括继承的方法
Method[] declaredMethods = clazz.getDeclaredMethods();
Method method = clazz.getDeclaredMethod("test", int.class, String.class);
4.2 Field成员变量
  • 1.设置值
void set(Object obj, Object value);
  • 2.获取值
get(Object obj);
Student student = new Student();
student.setName("张三");
Field nameField = Student.class.getDeclaredField("name");
nameField.setAccessible(true);
String name = (String)nameField.get(student);
System.out.println(name);
  • 3.忽略访问权限修饰符的安全检查
// 暴力反射
setAccessible(true);
  • 4.示例
// 反射调用成员变量
// 获取变量
Field age = clazz.getDeclaredField("age");
// 使私有成员允许访问
age.setAccessible(true);
// 为指定实例的变量赋值,静态变量,第一参数给null
age.set(o,22);
// 访问指定实例变量的值,静态变量,第一参数给null
age.get(o);

@Data
class Student{
    private String name;
}
4.3 Constructor构造方法
  • 1.创建对象
T newInstance(Object ...initargs)
  • 2.如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法
//执行无参构造创建对象
Object o = clazz.newInstance();
//执行有参构造创建对象
clazz.newInstance();
clazz.getConstructor(int.class,String.class);//获取构造方法
4.4 Method方法对象
  • 1.执行方法
Object invoke(Object obj,Object... args)
  • 2.获取方法名称
String getName获取方法名
  • 3.示例
// 反射调用成员方法
Method m = clazz.getDeclaredMethod("test",String.class);
m.setAccessible(true);//使私有方法允许被调用
m.invoke(o, "你好");//让指定实例来执行该方法
五、示例
package learning.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @Author wangyouhui
 * @Description 反射
 */
public class ReflectTest {
    private String name;
    private int age;

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


    public static void main(String[] args) throws Exception {
        Class<?> clazz = Class.forName("learning.reflect.ReflectTest");
        //获取包名
        String packageName = clazz.getPackage().getName();
        //获取类名
        String simpleName = clazz.getSimpleName();
        //获取完整类名
        String name = clazz.getName();

        //获取成员变量定义信息
        // 获取所有公开的成员变量,包括继承变量
        Field[] fields = clazz.getFields();
        // 获取本类定义的成员变量,包括私有,但不包括继承的变量
        Field[] declaredFields = clazz.getDeclaredFields();
        Field field = clazz.getField("name");
        Field declaredField = clazz.getDeclaredField("name");

        //获取构造方法定义信息
        //获取公开的构造方法
        Constructor<?> constructor = clazz.getConstructor(String.class);
        //获取所有的公开的构造方法
        Constructor<?>[] constructors = clazz.getConstructors();
        //获取所有的构造方法,包括私有
        Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
        Constructor<?> declaredConstructor = clazz.getDeclaredConstructor(int.class, String.class);

        //获取方法定义信息
        //获取所有可见的方法,包括继承的方法
        Method[] methods = clazz.getMethods();
        //获取本类定义的的方法
        Method test = clazz.getMethod("test", String.class);
        //获取本类定义的的方法,包括私有,不包括继承的方法
        Method[] declaredMethods = clazz.getDeclaredMethods();
        Method method = clazz.getDeclaredMethod("test", int.class, String.class);

        //反射新建实例
        //执行无参构造创建对象
        Object o = clazz.newInstance();
        //执行有参构造创建对象
        clazz.newInstance();
        clazz.getConstructor(int.class,String.class);//获取构造方法

        // 反射调用成员变量
        // 获取变量
        Field age = clazz.getDeclaredField("age");
        // 使私有成员允许访问
        age.setAccessible(true);
        // 为指定实例的变量赋值,静态变量,第一参数给null
        age.set(o,22);
        // 访问指定实例变量的值,静态变量,第一参数给null
        age.get(o);

        // 反射调用成员方法
        Method m = clazz.getDeclaredMethod("test",String.class);
        m.setAccessible(true);//使私有方法允许被调用
        m.invoke(o, "你好");//让指定实例来执行该方法
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

王佑辉

老板,赏点吧

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

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

打赏作者

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

抵扣说明:

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

余额充值