com.ideaaedi.commonds.lambda.SerializedLambdaHelper Maven / Gradle / Ivy
The newest version!
package com.ideaaedi.commonds.lambda;
import org.apache.commons.lang3.StringUtils;
import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* SerializedLambda 工具类
*
* @author JustryDeng
* @since 2100.7.2
*/
public class SerializedLambdaHelper {
public static FieldNameParser defaultFieldNameParser = new FieldNameParser(){};
/**
* @see SerializedLambdaHelper#getFieldName(SFunction)
*/
public static String getFieldName(SFunction sFunction) {
return getFieldName(sFunction, defaultFieldNameParser);
}
/**
* 获取字段名称
*/
public static String getFieldName(SFunction sFunction, FieldNameParser fieldNameParser) {
return getFieldName(getSerializedLambda(sFunction), fieldNameParser);
}
/**
* 获取lambda表达式字段名称
*
* 假设你的lambda表达式部分是这样写的:Person::getFirstName
,
* 那么,此方法的目的就是获取到getFirstName方法对应的(Person类中的对应字段的)字段名
*
*/
public static String getFieldName(SerializedLambda serializedLambda, FieldNameParser fieldNameParser) {
String implClassLongName = getImplClassLongName(serializedLambda);
String implMethodName = getImplMethodName(serializedLambda);
try {
return fieldNameParser.parseFieldName(Class.forName(implClassLongName), implMethodName);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
/**
* 获取方法名
*/
public static String getMethodName(SFunction sFunction) {
return getImplMethodName(getSerializedLambda(sFunction));
}
/**
* 获取全类名
*/
public static String getClassName(SFunction sFunction) {
return getImplClassLongName(getSerializedLambda(sFunction));
}
/**
* 获取lambda表达式中,实现方法的方法名
*
* 说明:
* 假设你的lambda表达式部分是这样写的:Person::getFirstName
,
* 那么这里获取到的就是Person.getFirstName()的方法名getFirstName
*
*
* @param serializedLambda
* serializedLambda对象
* @return 实现方法的方法名
* 形如:getFirstName
*/
private static String getImplMethodName(SerializedLambda serializedLambda) {
return serializedLambda.getImplMethodName();
}
/**
* 获取lambda表达式中,实现方法的类的全类名
*
* 说明:
* 假设你的lambda表达式部分是这样写的:Person::getFirstName
,
* 那么这里获取到的就是Person的全类名,形如:com.example.lambda.test.Person
*
*
* @param serializedLambda
* serializedLambda对象
* @return 实现方法的类的全类名
* 形如:com.example.lambda.test.Person
*/
private static String getImplClassLongName(SerializedLambda serializedLambda) {
return serializedLambda.getImplClass().replace("/", ".");
}
/**
* 获取SerializedLambda实例
*
* @param potentialLambda
* lambda实例
* @return SerializedLambda实例
*/
private static SerializedLambda getSerializedLambda(T potentialLambda) {
try{
Class> potentialLambdaClass = potentialLambda.getClass();
Method writeReplaceMethod = potentialLambdaClass.getDeclaredMethod("writeReplace");
boolean isAccessible = writeReplaceMethod.canAccess(potentialLambda);
writeReplaceMethod.setAccessible(true);
Object writeReplaceObject = writeReplaceMethod.invoke(potentialLambda);
writeReplaceMethod.setAccessible(isAccessible);
if (writeReplaceObject == null || !SerializedLambda.class.isAssignableFrom(writeReplaceObject.getClass())) {
throw new IllegalArgumentException("Cannot find (SerializedLambda)writeReplaceObject. writeReplaceObject should not be " + writeReplaceObject);
}
return (SerializedLambda)writeReplaceObject;
} catch( NoSuchMethodException | IllegalAccessException | InvocationTargetException e ){
throw new IllegalArgumentException("getSerializedLambda occur exception.", e);
}
}
/**
* 字段名解析器
*/
public interface FieldNameParser {
/**
* 解析字段名
*
* 假设你的lambda表达式部分是这样写的:Person::getFirstName
,
* 那么,
* clazz就对应Person类
* methodName就对应getFirstName
*
*
* @param clazz 字段所在的类
* @param methodName 与字段相关的方法(如:该字段的getter方法)
* @return 解析字段名
*/
default String parseFieldName(Class> clazz, String methodName) {
return StringUtils.uncapitalize(methodName.substring("get".length()));
}
}
}