1 应用场景
利用反射,通过对象(类实例化)属性名称,修改对象(类实例化)属性的值。
此处感谢:TD_FAlmK。
2 修改类属性值
2.1 实体类
package com.company.designpattern.reflect;
import java.util.Objects;
/**
* 测试类,用于反射测试
* @author xindaqi
* @since 2020-11-26
*/
public class User {
private String name;
private String address;
private Integer age;
public User() {}
public User(String name, String address, Integer age) {
this.name = name;
this.address = address;
this.age = age;
}
@Override
public boolean equals(Object o) {
if(this == o) {
return true;
}
if(null == o || getClass() != o.getClass()) {
return false;
}
User that = (User) o;
return name.equals(that.name) && address.equals(that.address) && age == that.age;
}
@Override
public int hashCode() {
return Objects.hash(name, address, age);
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAddress(String address) {
this.address = address;
}
public String getAddress() {
return address;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getAge() {
return age;
}
@Override
public String toString() {
return "User:{" + "name: " + name
+ "address: " + address
+ "age: " + age
+ "}";
}
}
2.1 暴力修改
package com.company.designpattern.reflect;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* 反射测试
* @author xindaqi
* @since 2020-11-26
*/
public class ReflectTest {
public static void main(String[] args) throws Exception {
/**
* 类实例化
*/
User user = new User("xiaoxiao", "shenzhen", 10);
/**
* 反射获类
*/
Class<?> clazz = user.getClass();
/**
* 获取类中所有属性
*/
Field[] fields = clazz.getFields();
System.out.println("Methods in Class: " + fields);
/**
* 获取某个属性方法
* 如name属性的方法
*/
Field field = clazz.getDeclaredField("name");
/**
* 开启私有属性编辑权限
*/
field.setAccessible(true);
/**
* 设置属性值
*/
field.set(user, "dada");
Class s = field.getType();
System.out.println("data type: " + s);
System.out.println("Object name: " + field.getName());
System.out.println("暴力赋值: " + user.getName());
}
}
2.2 内省机制修改
package com.company.designpattern.reflect;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* 反射测试
* @author xindaqi
* @since 2020-11-26
*/
public class ReflectTest {
public static void main(String[] args) throws Exception {
/**
* 类实例化
*/
User user = new User("xiaoxiao", "shenzhen", 10);
/**
* 反射获类
*/
Class<?> clazz = user.getClass();
/**
* 内省机制
*/
PropertyDescriptor propertyDescriptor = new PropertyDescriptor("name", clazz);
Method setMethod = propertyDescriptor.getWriteMethod();
setMethod.invoke(user, "erer");
System.out.println("内省机制: " + user.getName());
}
}
3 小结
3.1 暴力修改
暴力修改private属性值,需要使用setAccessable(true)方法获取修改权限,否则会出现如下情况:
Exception in thread “main” java.lang.IllegalAccessException: Class com.company.designpattern.reflect.ReflectTest can not access a member of class com.company.designpattern.reflect.User with modifiers “private”
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)
at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)
at java.lang.reflect.Field.set(Field.java:761)
at com.company.designpattern.reflect.ReflectTest.main(ReflectTest.java:39)
3.2 内省模式
通过PropertyDescriptor获取属性类实例,调用getWriteMethod()获取属性的写方法,invoke即可设定属性值。