前言:
反射,可以在运行时期动态创建对象;获取对象的属性、方法;
实体类:
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