Lambda表达式序列化
lambda表达式序列化后我们可以得到实现接口和实现方法的信息。
复制public class Client {
public static void main(String[] args) {
SerializedLambda serializedLambda = resolve(User::getUsername);
System.out.println(serializedLambda);
}
private static class User {
public String getUsername() {
return "lisi";
}
}
/**
* 解析 lambda 表达式
*
* @param func 需要解析的 lambda 对象
* @param <T> 类型,被调用的 Function 对象的目标类型
* @return 返回解析后的结果
*/
private static <T> SerializedLambda resolve(SFunction<T, ?> func) {
try {
Method method = func.getClass().getDeclaredMethod("writeReplace");
method.setAccessible(true);
return (SerializedLambda) method.invoke(func);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@FunctionalInterface
private interface SFunction<T, R> extends Function<T, R>, Serializable {
}
}
函数式接口实现Serializable ,java会帮我们序列化成SerializedLambda 对象,包含了函数式接口和实现方法的信息。
复制public class Client {
public static void main(String[] args) {
String property = resolveProperty(User::getUsername);
System.out.println(property);
}
private static class User {
public String getUsername() {
return "lisi";
}
}
/**
* 解析 lambda 表达式
*
* @param func 需要解析的 lambda 对象
* @param <T> 类型,被调用的 Function 对象的目标类型
* @return 返回解析后的结果
*/
private static <T> SerializedLambda resolve(SFunction<T, ?> func) {
try {
Method method = func.getClass().getDeclaredMethod("writeReplace");
method.setAccessible(true);
return (SerializedLambda) method.invoke(func);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 将Lambda表达式转化为属性名称
*/
public static <T> String resolveProperty(SFunction<T, ?> function) {
SerializedLambda lambda = resolve(function);
if (Objects.isNull(lambda)) {
return "";
}
String methodName = lambda.getImplMethodName();
if (methodName.startsWith("is")) {
methodName = methodName.substring(2);
} else {
if (!methodName.startsWith("get") && !methodName.startsWith("set")) {
throw new IllegalArgumentException("Error parsing property name '" + methodName
+ "'. Didn't start with 'is', 'get' or 'set'.");
}
methodName = methodName.substring(3);
}
if (methodName.length() == 1 || (methodName.length() > 1 && !Character
.isUpperCase(methodName.charAt(1)))) {
methodName = methodName.substring(0, 1).toLowerCase(Locale.ENGLISH) + methodName.substring(1);
}
return methodName;
}
@FunctionalInterface
private interface SFunction<T, R> extends Function<T, R>, Serializable {
}
}
通过序列化数据,我们可以得到实现方法信息,如果是setter或Getter就可以获得属性信息。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通