文章目录
1. Field类
Field类中提供了操作变量的方式,可以对变量数据获取与设置,包括可以操作私有变量
1.2. Field类常用方法
public Object get(Object obj)
:通过对象实例获取对象中属性的数据obj
:是指定实例对象,可以通过Class的newInstance()方法获取,或使用Constructor构造方法
public void set(Object obj, Object value)
:通过对象实例设置属性数据obj
:是指定实例对象,可以通过Class的newInstance()方法获取,或使用Constructor构造方法value
:属性的数据
public void setAccessible(boolean flag)
:强制忽略安全检测调用获取非public修饰的属性public String getName()
:获取属性名称public Class<?> getType()
:获取属性类型public int getModifiers()
:获取属性修饰符
// 通过Class.forName获取Class类
Class<?> clazz = Class.forName("reflection.User");
// 通过Class的newInstance方法获取User对象实例
Object newInstance = clazz.newInstance();
// 获取类中指定属性
// 私有的
Field id = clazz.getDeclaredField("id");
// 公共的
Field age = clazz.getDeclaredField("age");
//1. `obj`:是指定要获取值的实例对象
Object object = age.get(newInstance);
System.out.println("object = " + object);
// 2. `public void set(Object obj, Object value)`:通过对象实例设置属性数据
// `obj`:是指定实例对象,可以通过Class的newInstance()方法获取,或使用Constructor构造方法
// `value`:属性的数据
age.set(newInstance, 18);
object = age.get(newInstance);
System.out.println("object = " + object);
System.out.println("newInstance = " + newInstance);
String name = age.getName();
System.out.println("name = " + name);
Class<?> type = age.getType();
System.out.println("type = " + type);
int modifiers = age.getModifiers();
System.out.println("modifiers = " + modifiers);
id.setAccessible(true);
// 私有变量获取与设置
Object object1 = id.get(newInstance);
System.out.println("object1 = " + object1);
id.set(newInstance, 111);
object1 = id.get(newInstance);
System.out.println("object1 = " + object1);
System.out.println("newInstance = " + newInstance);
2. Method类
Method类中提供了操作方法的方式,可以对方法获取或调用,包括可以操作私有方法
2.1. Method类常用方法
public String getName()
:获取方法名称public int getModifiers()
:获取方法修饰符public int getParameterCount()
:获取方法形参数量public Class<?> getReturnType()
:获取方法返回值类型public Class<?>[] getParameterTypes()
:获取方法形参类型public Object invoke(Object obj, Object... args)
:调用此方法obj
:是指定实例对象,可以通过Class的newInstance()方法获取,或使用Constructor构造方法args
:形参参数
public void setAccessible(boolean flag)
:强制忽略安全检测调用获取非public修饰的属性
// 获取User实例对象
Class<?> clazz = Class.forName("reflection.User");
Object newInstance = clazz.newInstance();
// 私有方法
Method method1 = clazz.getDeclaredMethod("method", Integer.class);
// 公共方法
Method method2 = clazz.getDeclaredMethod("method", String.class, String.class);
// 1. `public String getName()`:获取方法名称
String name = method2.getName();
System.out.println("name = " + name);
// 2. `public int getModifiers()`:获取方法修饰符
int modifiers = method2.getModifiers();
System.out.println("modifiers = " + modifiers);
// 3. `public int getParameterCount()`:获取方法形参数量
int parameterCount = method2.getParameterCount();
System.out.println("parameterCount = " + parameterCount);
// 4. `public Class<?> getReturnType()`:获取方法返回值类型
Class<?> returnType = method2.getReturnType();
System.out.println("returnType = " + returnType);
// 5. `public Class<?>[] getParameterTypes()`:获取方法形参类型
Class<?>[] parameterTypes = method2.getParameterTypes();
System.out.println("Arrays.toString(parameterTypes) = " + Arrays.toString(parameterTypes));
// 6. `public Object invoke(Object obj, Object... args)`:调用此方法
// 1. `obj`:是指定实例对象,可以通过Class的newInstance()方法获取,或使用Constructor构造方法
// 2. `args`:形参参数
System.out.println("====================================");
Object returnValue = method2.invoke(newInstance, "彭于晏", "男");
System.out.println("returnValue = " + returnValue);
// 打印newInstance对象
System.out.println("newInstance = " + newInstance);
// 7. `public void setAccessible(boolean flag)`:强制忽略安全检测调用获取非public修饰的属性
System.out.println("====================================");
String name1 = method1.getName();
System.out.println("name1 = " + name1);
// 调用非public修饰的方法必须设置setAccessible忽略安全检测
method1.setAccessible(true);
method1.invoke(newInstance, 1);
System.out.println("newInstance = " + newInstance);
3. Constructor类
Constructor类中提供了操作构造方法的方式,可以对构造方法获取或设置,包括可以操作私有的构造方法
3.1. Constructor类常用方法
public String getName()
:获取构造方法名称public int getModifiers()
:获取构造方法修饰符public int getParameterCount()
:获取构造方法形参数量public Class<?>[] getParameterTypes()
:获取构造方法形参类型public T newInstance(Object ... initargs)
:调用构造方法,并指定形参数据initargs
:形参参数
public void setAccessible(boolean flag)
:强制忽略安全检测调用获取非public修饰的属性
// 获取User实例对象
Class<?> clazz = Class.forName("reflection.User");
// 私有构造方法
Constructor<?> constructor1 = clazz.getDeclaredConstructor(Integer.class);
// 公共构造方法
Constructor<?> constructor2 = clazz.getDeclaredConstructor(Integer.class, String.class, String.class, Integer.class);
// 1. `public String getName()`:获取构造方法名称
String name = constructor2.getName();
System.out.println("name = " + name);
// 2. `public int getModifiers()`:获取构造方法修饰符
int modifiers = constructor2.getModifiers();
System.out.println("modifiers = " + modifiers);
// 3. `public int getParameterCount()`:获取构造方法形参数量
int parameterCount = constructor2.getParameterCount();
System.out.println("parameterCount = " + parameterCount);
// 4. `public Class<?>[] getParameterTypes()`:获取构造方法形参类型
Class<?>[] parameterTypes = constructor2.getParameterTypes();
System.out.println("Arrays.toString(parameterTypes) = " + Arrays.toString(parameterTypes));
// 5. `public T newInstance(Object ... initargs)`:调用构造方法,并指定形参数据
// 1. `initargs`:形参参数
System.out.println("====================================");
Object instance = constructor2.newInstance(1, "彭于晏", "男", 18);
System.out.println("instance = " + instance);
// 6. `public void setAccessible(boolean flag)`:强制忽略安全检测调用获取非public修饰的属性
System.out.println("====================================");
int modifiers1 = constructor1.getModifiers();
System.out.println("modifiers1 = " + modifiers1);
// 调用私有的构造方法需要设置忽略安全检测
constructor1.setAccessible(true);
Object instance1 = constructor1.newInstance(1);
System.out.println("instance1 = " + instance1);
Field、Method、Constructor结合使用
public static void main(String[] args) throws Exception {
// 获取Student的Class对象
Class<?> clazz = Class.forName("reflection.Student");
// 获取构造方法
Constructor<?> constructor = clazz.getConstructor(Integer.class, String.class, String.class);
// 创建User对象实例-->此实例也用于后面的方法和属性使用
Object instance = constructor.newInstance(1, "古天乐", "男");
System.out.println("instance = " + instance);
// 获取属性
Field id = clazz.getDeclaredField("id");
Field name = clazz.getDeclaredField("name");
Field gender = clazz.getDeclaredField("gender");
// 设置setAccessible强制忽略安全检测调用非public修饰的属性
id.setAccessible(true);
name.setAccessible(true);
gender.setAccessible(true);
// 获取属性数据
System.out.println("修改前");
Object idValue = id.get(instance);
System.out.println("idValue = " + idValue);
Object nameValue = name.get(instance);
System.out.println("nameValue = " + nameValue);
Object genderValue = gender.get(instance);
System.out.println("genderValue = " + genderValue);
// 设置属性数据
id.set(instance, 2);
name.set(instance, "古校长");
gender.set(instance, "男神");
// 获取属性数据
System.out.println("修改后");
Object idValue1 = id.get(instance);
System.out.println("idValue1 = " + idValue1);
Object nameValue1 = name.get(instance);
System.out.println("nameValue1 = " + nameValue1);
Object genderValue1 = gender.get(instance);
System.out.println("genderValue1 = " + genderValue1);
// 获取方法
// 获取get方法
Method getIdMethod = clazz.getMethod("getId");
Method getNameMethod = clazz.getMethod("getName");
Method getGenderMethod = clazz.getMethod("getGender");
// 调用方法
System.out.println("修改前");
Object result1 = getIdMethod.invoke(instance);
System.out.println("result1 = " + result1);
Object result2 = getNameMethod.invoke(instance);
System.out.println("result2 = " + result2);
Object result3 = getGenderMethod.invoke(instance);
System.out.println("result3 = " + result3);
// 获取set方法
Method setIdMethod = clazz.getMethod("setId", Integer.class);
Method setNameMethod = clazz.getMethod("setName", String.class);
Method setGenderMethod = clazz.getMethod("setGender", String.class);
// 调用方法
setIdMethod.invoke(instance, 1);
setNameMethod.invoke(instance, "古天乐");
setGenderMethod.invoke(instance, "男神");
// 调用方法
System.out.println("修改后");
result1 = getIdMethod.invoke(instance);
System.out.println("result1 = " + result1);
result2 = getNameMethod.invoke(instance);
System.out.println("result2 = " + result2);
result3 = getGenderMethod.invoke(instance);
System.out.println("result3 = " + result3);
// 获取toString方法并调用
Method toString = clazz.getMethod("toString");
Object result = toString.invoke(instance);
System.out.println("result = " + result);
System.out.println("instance = " + instance);
}
4.JSON与Java对象互转工具类
/**
* JSON互转工具类
*/
public class JSON {
/**
* Java对象转JSON字符串方法
*
* @param obj 传入需要转换的Java对象
* @return 返回转换后的JSON字符串
*/
public static String toJSONString(Object obj) {
// 1. 获取传入的对象的Class类
Class<?> clazz = obj.getClass();
// 2. 获取所有的属性
Field[] fields = clazz.getDeclaredFields();
// 定义StringBuilder拼接字符串
StringBuilder sb = new StringBuilder("{");
// 3. 遍历所有的属性
for (int i = 0; i < fields.length; i++) {
// 4. 设置setAccessible强制忽略安全检测
fields[i].setAccessible(true);
try {
// 5. 获取属性名称和属性值和属性类型
Class<?> fieldType = fields[i].getType();
String fieldName = fields[i].getName();
Object fieldValue = fields[i].get(obj);
// 6. 拼接JSON字符串
// 判断属性类型是否是String
if (fieldType == String.class) {
// 判断是否是最后一个属性
if (i == fields.length - 1) {
// 拼接数据
// {"age":18,"gender":"男","id":1,"name":"彭于晏"}
sb.append("\"" + fieldName + "\":" + "\"" + fieldValue + "\"}");
continue;
}
sb.append("\"" + fieldName + "\":" + "\"" + fieldValue + "\",");
continue;
}
// 判断是否是最后一个属性
if (i == fields.length - 1) {
// 拼接数据
// {"age":18,"gender":"男","id":1,"name":"彭于晏"}
sb.append("\"" + fieldName + "\":" + "" + fieldValue + "}");
continue;
}
sb.append("\"" + fieldName + "\":" + "" + fieldValue + ",");
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return sb.toString();
}
/**
* 将JSON字符串转为Java对象
*
* @param jsonString JSON字符串
* @param clazz 需要转换的Class类型
* @param <T> 泛型类型变量
* @return 返回转换后的对象
*/
public static <T> T parseObject(String jsonString, Class<T> clazz) {
// 通过Class获取实例对象
try {
T instance = clazz.newInstance();
// 解析JSON字符串
// {"id":1,"name":"彭于晏","gender":"男"}
// 去除JSON字符串的大括号以及双引号
jsonString = jsonString
.replace("{", "")
.replace("}", "")
.replace("\"", "");
// 逗号分割
String[] split = jsonString.split(",");
// 遍历split分割的数组
for (String keyValue : split) {
// 再通过冒号:分割
String[] keyAndValue = keyValue.split(":");
// 获取属性
Field field = clazz.getDeclaredField(keyAndValue[0]);
// 设置忽略安全检测
field.setAccessible(true);
// 获取属性的类型
Class<?> fieldType = field.getType();
// 判断type类型
if (fieldType == String.class) {
field.set(instance, keyAndValue[1]);
continue;
}
// 如果不是String就是Integer
field.set(instance, Integer.valueOf(keyAndValue[1]));
}
// 返回T泛型类型对象
return instance;
} catch (Exception e) {
e.printStackTrace();
}
// 如果出现异常则返回null
return null;
}
}