package com.test.mybatisplus.reflect;
import com.alibaba.fastjson.JSONObject;
import com.test.mybatisplus.entity.PressEntity;
import lombok.extern.slf4j.Slf4j;
import java.awt.print.Book;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
* @Description:反射工具
* @Return:
* @Time: 2021/1/6 11:39
*/
@Slf4j
public class ReflectUtil {
/**
* 获取字段对应值,并转为String类型,空值返回空字符串
* @param fieldName
* @param obj
* @return
*/
public static synchronized String getStringValue(String fieldName,Object obj) throws ReflectiveOperationException{
Object objectValue = getValueByGetter(fieldName,obj);
if (objectValue == null){
return "";
}
String result = objectValue.toString();
//如果类型为BigDecimal,去掉末尾的0
if (objectValue instanceof BigDecimal){
BigDecimal value = (BigDecimal) objectValue;
value = value.stripTrailingZeros();
result = value.toPlainString();
}else if (objectValue instanceof Date){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
result = sdf.format((Date)objectValue).replace(" 00:00:00", "");
}
return result.trim();
}
public static Object getValueByGetter (String fieldName,Object obj) throws ReflectiveOperationException {
Method getter = getGetter(fieldName, obj.getClass());
if (getter != null){
return getter.invoke(obj);
}
return null;
}
public static Object setValueBySetter (String fieldName,Object obj) throws ReflectiveOperationException {
Method setter = getSetter(fieldName, obj.getClass());
if (setter == null){
throw new ReflectiveOperationException("没有set方法");
}
return setter.invoke(obj);
}
/**
* 获取get方法
* @param fieldName
* @param cls
* @return
*/
public static Method getGetter(String fieldName,Class<?> cls){
for (Method method : cls.getMethods()) {
if (method.getName().equalsIgnoreCase("get".concat(fieldName)) && method.getParameterTypes().length == 0){
return method;
}
}
return null;
}
/**
* 获取set方法
* @param fieldName
* @param cls
* @return
*/
public static Method getSetter(String fieldName,Class<?> cls){
for (Method method : cls.getMethods()) {
if (method.getName().equalsIgnoreCase("set".concat(fieldName)) && method.getParameterTypes().length == 0){
return method;
}
}
return null;
}
/**
* 通过属性名获取Field对象
* @param fieldName
* @param cls
* @return
*/
public static synchronized Field getFieldByName(String fieldName,Class<?> cls){
Field[] fields =cls.getDeclaredFields();
for (Field field : fields){
if (field.getName().equals(fieldName)){
return field;
}
}
if (cls.getSuperclass() != null){
return getFieldByName(fieldName,cls.getSuperclass());
}
return null;
}
/**
* 通过对象.class获取所有Fields,包括父类
* @param cls
* @return
*/
public static List<Field> listFields(Class<?> cls){
Field[] fs = cls.getDeclaredFields();
List<Field> fields = new ArrayList<>(Arrays.asList(fs));
if (cls.getSuperclass() !=null){
fields.addAll(listFields(cls.getSuperclass()));
}
return fields;
}
public static boolean fieldExist(String fieldName,Class<?> cls){
return getFieldByName(fieldName, cls) !=null;
}
public static void main(String[] args) throws ReflectiveOperationException {
PressEntity pressEntity = new PressEntity();
pressEntity.setName("张三");
pressEntity.setShortPress("dd");
Field field = ReflectUtil.getFieldByName("name", pressEntity.getClass());
System.out.println("反射获取Field对象:" + field);
String name1 = ReflectUtil.getStringValue("name", pressEntity);
System.out.println("反射获取name值:" + name1);
String shortPress = ReflectUtil.getStringValue("ShortPress", pressEntity);
System.out.println("反射获取shortPress值:" + shortPress);
List<Field> fields = ReflectUtil.listFields(pressEntity.getClass());
System.out.println("反射获取所有filed,包括父类"+fields.toString());
}
}
//在日常的第三方应用开发过程中,经常会遇到某个类的某个成员变量、方法或是属性是私有的或是只对系统应用开放,
// 这时候就可以利用Java的反射机制通过反射来获取所需的私有成员或是方法。当然,也不是所有的都适合反射,
// 之前就遇到一个案例,通过反射得到的结果与预期不符。阅读源码发现,经过层层调用后在最终返回结果的地方对应用的权限进行了校验,
// 对于没有权限的应用返回值是没有意义的缺省值,否则返回实际值起到保护用户的隐私目的。
//
// 反射机制的相关类
// 与Java反射相关的类如下:
//
// 类名 用途
// Class类 代表类的实体,在运行的Java应用程序中表示类和接口
// Field类 代表类的成员变量(成员变量也称为类的属性)
// Method类 代表类的方法
// Constructor类 代表类的构造方法
// Class类
// Class代表类的实体,在运行的Java应用程序中表示类和接口。在这个类中提供了很多有用的方法,这里对他们简单的分类介绍。
//
// 获得类相关的方法
// 方法 用途
// asSubclass(Class<U> clazz) 把传递的类的对象转换成代表其子类的对象
// Cast 把对象转换成代表类或是接口的对象
// getClassLoader() 获得类的加载器
// getClasses() 返回一个数组,数组中包含该类中所有公共类和接口类的对象
// getDeclaredClasses() 返回一个数组,数组中包含该类中所有类和接口类的对象
// forName(String className) 根据类名返回类的对象
// getName() 获得类的完整路径名字
// newInstance() 创建类的实例
// getPackage() 获得类的包
// getSimpleName() 获得类的名字
// getSuperclass() 获得当前类继承的父类的名字
// getInterfaces() 获得当前类实现的类或是接口
// 获得类中属性相关的方法
// 方法 用途
// getField(String name) 获得某个公有的属性对象
// getFields() 获得所有公有的属性对象
// getDeclaredField(String name) 获得某个属性对象
// getDeclaredFields() 获得所有属性对象
// 获得类中注解相关的方法
// 方法 用途
// getAnnotation(Class<A> annotationClass) 返回该类中与参数类型匹配的公有注解对象
// getAnnotations() 返回该类所有的公有注解对象
// getDeclaredAnnotation(Class<A> annotationClass) 返回该类中与参数类型匹配的所有注解对象
// getDeclaredAnnotations() 返回该类所有的注解对象
// 获得类中构造器相关的方法
// 方法 用途
// getConstructor(Class...<?> parameterTypes) 获得该类中与参数类型匹配的公有构造方法
// getConstructors() 获得该类的所有公有构造方法
// getDeclaredConstructor(Class...<?> parameterTypes) 获得该类中与参数类型匹配的构造方法
// getDeclaredConstructors() 获得该类所有构造方法
// 获得类中方法相关的方法
// 方法 用途
// getMethod(String name, Class...<?> parameterTypes) 获得该类某个公有的方法
// getMethods() 获得该类所有公有的方法
// getDeclaredMethod(String name, Class...<?> parameterTypes) 获得该类某个方法
// getDeclaredMethods() 获得该类所有方法
// 类中其他重要的方法
// 方法 用途
// isAnnotation() 如果是注解类型则返回true
// isAnnotationPresent(Class<? extends Annotation> annotationClass) 如果是指定类型注解类型则返回true
// isAnonymousClass() 如果是匿名类则返回true
// isArray() 如果是一个数组类则返回true
// isEnum() 如果是枚举类则返回true
// isInstance(Object obj) 如果obj是该类的实例则返回true
// isInterface() 如果是接口类则返回true
// isLocalClass() 如果是局部类则返回true
// isMemberClass() 如果是内部类则返回true
// Field类
// Field代表类的成员变量(成员变量也称为类的属性)。
//
// 方法 用途
// equals(Object obj) 属性与obj相等则返回true
// get(Object obj) 获得obj中对应的属性值
// set(Object obj, Object value) 设置obj中对应属性值
// Method类
// Method代表类的方法。
//
// 方法 用途
// invoke(Object obj, Object... args) 传递object对象及参数调用该对象对应的方法
// Constructor类
// Constructor代表类的构造方法。
//
// 方法 用途
// newInstance(Object... initargs) 根据传递的参数创建类的对象
反射 工具类ReflectUtil
最新推荐文章于 2024-04-06 14:25:19 发布