反射复习

前言:

反射,可以在运行时期动态创建对象;获取对象的属性、方法;

实体类:

public class users {
    private Integer id =20;
    private String name;
    public users() {
        System.out.println("无参构造函数");
    }
    public users(Integer a) {
        System.out.println("带一个参数的构造函数:"+a);
    }
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

通过反射调用构造函数,创建类:

    Class<?> classOne = Class.forName("entity.users");
        //默认调用无参的构造函数 如果实体类中没有构造函数就会报错
        //at java.base/java.lang.Class.newInstance(Unknown Source)
        users usersZero = (users) classOne.newInstance();

        //获得构造函数
        //默认调用无参的构造函数
        Constructor<?> constructor = classOne.getConstructor();
        users userOne = (users) constructor.newInstance();
        //可以自己选择调用什么参数的构造函数
        Constructor<?> constructorNew = classOne.getDeclaredConstructor(Integer.class);
        users userTwo = (users) constructorNew.newInstance(1);  

输出:

无参构造函数
无参构造函数
带一个参数的构造函数:1

通过反射得到类的属性:
这里有3个注意点:
一:
getDeclaredFielsd()方法可以获取全部自定义的属性,但是不能得到继承的属性
getFields()只能获取公共属性 但可以得到继承的属性
二:
如果要对私有的属性进行赋值或者修改
setAccessible()方法可以设置是否访问和修改私有属性

fields[0].setAccessible(true);
fields[0].set(xx, 11);
System.out.println(fields[0].get(xx));

三:
getDeclaredFielsd()获得属性还有一个自带的:$jacocoData
莫名其妙的,明明我创建的实体类没有这玩意。很奇怪,搜也搜不到答案

搜到的答案:原因不明

JacocoData是公司进行覆盖率检查的工具,  
平时是synthetic状态。本机打印应该没有这个变量,  
但是发到线上后就会有。

实例:

    Class<?> classOne = Class.forName("entity.users");
        users usersNow = (users) classOne.newInstance();
        //得到指定的属性
        Field field = classOne.getDeclaredField("id");
        field.setAccessible(true);
        System.out.println(field.getName()+":"+field.get(usersNow));
        //得到全部属性
        Field[] fields = classOne.getDeclaredFields();
        for(Field one :fields) {
            one.setAccessible(true);
            System.out.println(one.getName()+":"+one.get(usersNow));
        }

输出:

无参构造函数
id:20
id:20
name:哈哈
$jacocoData:[Z@7403c468

注意:
setAccessible(true)

意思是允许调用私有的构造方法,  
所以在一些使用单例模式的程序中要注意防范这种反射的攻击。

通过反射创建类的方法:

Class<?> classOne = Class.forName("entity.users");
        users usersNow = (users) classOne.newInstance();
        Method method = classOne.getDeclaredMethod("setId",Integer.class);
        method.invoke(usersNow, 12); 
        int a = usersNow.getId();
        System.out.println(a);
        }

输出:

无参构造函数
12
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值