有时候在处理属性字段名称时,由于是手动写属性名称,难免会出错,导致写的名称与某个实体的Field名称不一致。
借助JDK8的函数式编程的新特性,可以很友好的解决这一问题。
通过getter方法即可获得其对象的属性名称。
使用User举例
class User {
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
首先需要定义一个函数式接口 入参类型T,出参类型R
/**
* 字段属性函数
*
* @param <T>
* @param <R>
*/
@FunctionalInterface
public interface PropertyFunc<T, R> extends Function<T, R>, Serializable {
}
定义基于PropertyFunc的Class解析工具类
class ClassUtil {
/**
* 根据字段函数获取字段名称
*
* @param field entity属性
* @return - fieldName
*/
public static <T> String getFieldName(PropertyFunc<T, ?> field) {
return toFieldName(field.getClass(), field);
}
static String toFieldName(Class<?> clazz, PropertyFunc<?, ?> field) {
try {
Method method = clazz.getDeclaredMethod("writeReplace");
method.setAccessible(true);
SerializedLambda lambda = (SerializedLambda) method.invoke(field);
String methodName = lambda.getImplMethodName();
return StringUtils.uncapitalize(methodName.startsWith("get")
? methodName.substring(3)
: (methodName.startsWith("is") ? methodName.substring(2) : methodName));
} catch (Exception e) {
if (!"Object".equals(clazz.getSuperclass().getSimpleName())) {
return toFieldName(clazz.getSuperclass(), field);
}
return null;
}
}
}
注:工具类中使用到的“writeReplace”,前面章节已提到过。
使用
class Test {
public static void main(String[] args) {
String fieldName = ClassUtil.getFieldName(User::getUsername);
System.out.println(fieldName); // 结果 username
}
}