带你了解反射

1 什么是反射?

        在Java中,反射(Reflection)是一种强大的工具,它允许程序在运行时(runtime)进行自我检查(introspection)和修改。通过反射,Java代码可以获取类的内部信息(如字段、方法、构造器等),并且可以动态地创建和操作这些类的实例。

简单来说:反射就是类在运行期间,把类中成员抽取为其他类的过程就是反射。

2 为什么使用反射?

        反射是为了解决在运行期,对某个实例一无所知的情况下,如何调用其方法或属性。

例子:spring框架中只需要传入类的路径----spring框架就会帮你创建类的对象。 反射在许多框架和库中被广泛使用,如Spring、Hibernate等。这些框架使用反射来动态地加载和配置类,从而提供了高度的灵活性和可扩展性。

3 class类对象

        每个类都有一个与之关联的Class对象。这个对象包含了类的元数据信息(metadata),如类的名称、包名、实现的接口、父类、字段、方法等。

3.1获得class反射类方式

​
第一种: 通过类名.class属性

Class<Student> aClass = Student.class;

第二种: 通过类路径获取

Class aClass1 = Class.forName("com.yzf.test.Student");

第三种: 通过对象名获取反射类型

Student student = new Student();
Class aClass2 = student.getClass();


​

3.2常用class方法

1.根据反射类得到实例对象 newInstance()

2.得到反射类上的注解对象。getAnnotation()

3.3获取类信息

        使用反射,你可以获取类的字段、方法、构造器等信息。这些信息存储在FieldMethodConstructor等类中。

①获取Method方法类对象:

getDeclaredMethods(): 得到本类中所有的方法。

getDeclaredMethod("方法名",参数类型):获取本类中指定的方法对象

getMethods():获取本类以及父辈类中public修饰的方法。

getMethod("方法名",参数类型):获取本类以及父辈类中指定public修饰的方法。

调用反射类方法:

//?通配符
Class<?> aClass = Class.forName("entity.Student");
Object o = aClass.newInstance();//实例对象
Method show = aClass.getMethod("show");
Object invoke = show.invoke(o);//.invoke调用实例对象中的方法
System.out.println(invoke);

System.out.println("----------------");
Method stu = aClass.getDeclaredMethod("stu",String.class);//带参
stu.setAccessible(true);//设置允许访问私有成员
Object invoke1 = stu.invoke(o,"语文");
System.out.println(invoke1);

②获取Filed属性对象对象:

getDeclaredFields();//得到本类中所有的属性
getDeclaredField("方法名",参数类型);//获取本类中指定的属性

getFields();//获取本类以及父辈类中public修饰的属性
getMethodFields("方法名",参数类型);//获取本类以及父辈类中指定public修饰的属性

属性对象赋值:

 Class<Student> studentClass = Student.class;//获取反射类
        Student student = studentClass.newInstance();//实例对象
        Field[] declaredFields = studentClass.getDeclaredFields();//本类所有属性对象
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField.getName());//getName()得到成员属性名
            //自定义注解
            myAnnotation annotation = declaredField.getAnnotation(myAnnotation.class);
            //注解的值
            System.out.println(annotation.value());
        }
        Field name = studentClass.getDeclaredField("name");//获取指定属性对象
        name.setAccessible(true);//设置允许访问私有成员
        name.set(student,"lll");//set方法赋值
        System.out.println(student);

4 案例

        在properties属性文件中指定类的路径,通过反射完成类对象的创建以及类中属性的赋值。

第一步:properties属性文件(类路径获取)

className=entity.Student

第二步:主函数测试

public class Test06 {
    public static void main(String[] args) throws  Exception{
        //加载属性文件
        InputStream inputStream=Test06.class.getClassLoader().getResourceAsStream("properties.properties");
        //属性类对象
        Properties properties=new Properties();
        properties.load(inputStream);
        //属性类读取属性文件中指定的key的值
        String className= properties.getProperty("className");
        //根据类路径得到反射对象
        Class<?> aClass = Class.forName(className);
        //反射类创建实例对象
        Object o = aClass.newInstance();
        System.out.println(o);

        //该类所有方法
        Field[] declaredFields = aClass.getDeclaredFields();
        //遍历赋值
        for (Field declaredField : declaredFields) {
            declaredField.setAccessible(true);//设置允许访问私有成员
            declaredField.set(o,new Random().nextInt(10)+"");
        }
        System.out.println(o);
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值