Java反射

Java反射

反射的原理

在我们编写好一个Java程序后,这个程序并不是直接就可以在机器上运行,而是需要编译器将程序编译为字节码(.class文件),然后通过JVM解释器,将字节码解释为具体系统可以读懂的数据。反射就是直接从字节码中提取信息。这也是Java一次编写,到处运行的原理。

反射的使用

反射主要基于class包,使用Class包中的一个静态方法Class.forName来加载类

//User是我们自己设置的类
//加载需要完整的包名
Class<User> mClass = (User) Class.forName("com.company.User")

这样我们就得到了一个Class对象(注意,是class对象,而不是User对象),这里还有一点就是,一个具体类的class对象,只会存在一个。
随后可以使用这个class对象来构建一个user对象

//Java已经过时的方法
User user = mClass.newInstance();
//Java目前推荐的方法
User user = (User) mClass.getConstructor().newInstance();

但是这并不是反射的主要作用,反射的主要目的是获取类中私有的对象。

获取类中的对象

获取类中对象有两种方法

//第一种方法会返回所有可以访问的参数
		Field[] fields = mClass.getFields();
//第二种方法会返回所有参数,不论是否有权限访问
        Field[] fields1 = mClass.getDeclaredFields();
//还可以指定返回参数,参数是目标的变量名
        Field field = mClass.getField("name");
//同样也有declared方法
        Field field1 = mClass.getDeclaredField("name");

获取到field后,我们可以通过一些内置方法得到参数的相关信息

for (Field field : fields1) {
            System.out.println(Modifier.toString(field.getModifiers()) + " " + 
                    field.getGenericType().toString() + " " + 
                    field.toString());
        }

获取类中的方法

//获取方法对象,getMrthods获取的方法包括了父类的方法
		Method[] methods = mClass.getMethods();
//与上面类似,但没有父类方法
        Method[] methods1 = mClass.getDeclaredMethods();
//获取构造方法
        Constructor[] constructors = mClass.getDeclaredConstructors();
        Constructor[] constructors1 = mClass.getConstructors();

使用获取到的方法

在使用获取到的方法之前,需要先创建对象,创建对象的方法在上面已经介绍过了。获取到对象和方法后,可以使用invoke方法来执行目标方法

//创建一个对象,后面是使用构造方法时传入的参数
User user = (User) mClass.getConstructor(int.class, String.class, String.class).newInstance(1, "hyb", "123456");
//通过方法名和参数获取方法对象,这里需要参数的原因是有重载
Method method = mClass.getMethod("print", String.class);
//运行方法,这里需要绑定对象和传入参数
method.invoke(user, "Use this method by reflection");

修改获取到的对象

获取到的对象有时需要修改,方法步骤见下

		User user = (User) mClass.getConstructor(int.class, String.class, String.class).newInstance(1, "hyb", "123456");
        Field field = mClass.getDeclaredField("name");
        field.setAccessible(true);
        field.set(user, "my name is xxx");
        System.out.print(user.getName());
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值