Java SAO操作-使用lambda代替字符串
获取lambda的详细信息
要说啥?
Java8新增了lambda表达式,最常见的用法是配合Stream
做集合操作。下面是一种类似彩蛋的东西可以妙用到某些场合。
一般用法,比如下面这样
Optional.of(1L).ifPresent(number -> {System.out.println(number);
});
复制代码
或者简化成这样
Optional.of(1L).ifPresent(System.out::println);
复制代码
有什么办法能获取到System.out::println
里面的方法名字符串String methodName = "println"
?
啥效果?
执行代码
FnConverter<Foo> fnConverter = new FnConverter<>();
String fieldName = fnConverter.convertFnToString(Foo::getBar);
System.out.println("方法名:"+fieldName);
复制代码
输出
方法名:bar
怎么做?
第一步:定义一个FunctionalInterface
(敲黑板,画重点extends Serializable
)
/*** @author Frank*/
@FunctionalInterface
public interface Fn<T> extends Serializable {Object apply(T source);
}
复制代码
第二布:准备个类(酱油)
import lombok.Data;/*** @author liuyuyu*/
@Data
public class Foo {private Integer bar;
}
复制代码
第三步:获取Fn
的信息的工具类
import java.beans.Introspector;import java.lang.invoke.SerializedLambda;import java.lang.reflect.Method;/*** @author Frank*/public class Reflections {private Reflections() {}public static String fnToFieldName(Fn fn) {try {Method method = fn.getClass().getDeclaredMethod("writeReplace");method.setAccessible(Boolean.TRUE);SerializedLambda serializedLambda = (SerializedLambda) method.invoke(fn);String getter = serializedLambda.getImplMethodName();String fieldName = Introspector.decapitalize(getter.replace("get", ""));return fieldName;} catch (ReflectiveOperationException e) {throw new RuntimeException(e);}}}复制代码
画重点SerializedLambda serializedLambda = (SerializedLambda) method.invoke(fn);
第四步:写个梨子跑起来
/*** @author liuyuyu*/
public class FnConverter<T> {public String convertFnToString(Fn<T> fn){return Reflections.fnToFieldName(fn);}public static void main(String[] args) {FnConverter<Foo> fnConverter = new FnConverter<>();String fieldName = fnConverter.convertFnToString(Foo::getBar);System.out.println("方法名:"+fieldName);}
}复制代码
Run
方法名:bar
复制代码
啥原理?
Serializable
是Java对象序列化的接口,凡是实现这个接口(interface是继承,也算)Java都要提供序列化和反序列化的方法(ObjectInputStream/ObjectOutputStream
可能会让你想起点什么)。
但是lambda比较特殊,它是一个方法,可以认为是一个动作(或者说是功夫?比如九阴真经),没办法直接保存,Java提供了SerializedLambda
这个类保存lambda的信息。
public final class SerializedLambda implements Serializable {private static final long serialVersionUID = 8025925345765570181L;private final Class<?> capturingClass;private final String functionalInterfaceClass;private final String functionalInterfaceMethodName;private final String functionalInterfaceMethodSignature;private final String implClass;private final String implMethodName;private final String implMethodSignature;private final int implMethodKind;private final String instantiatedMethodType;private final Object[] capturedArgs;//省略之后代码
}
复制代码
知道了这个隐藏(彩)特性(蛋),我们回头看看刚才黑板上画的重点
@FunctionalInterface //lambda
public interface Fn<T> extends Serializable //序列化接口
复制代码
两个条件满足
因为这个东西是个隐藏(彩)特性(蛋),我们不能直接获取到SerializedLambda
。直接上反射!
SerializedLambda serializedLambda = (SerializedLambda) method.invoke(fn);
这样,我们就可以获取到lambda的方法名
还能干啥?
在框架设计的时候,很多场景要获取类的属性,Java8以前API设计的时候只能用字符串方式,如果是Java8,就可以避免字符串。
大家可以打开(骗星)栗子,直接运行代码感受一下。
Mybatis通用Mapper增强
lambda meta信息获取demo
转载于:https://juejin.im/post/5b0948d06fb9a07aa6323866
Java SAO操作-使用lambda代替字符串相关推荐
- STL之multiset中equal_range,multimap中的equal_range,bitset容器,string字符串操作,lambda表达式
1multiset中用equal_range来遍历所有的元素 #include <set> #include <iostream> using namespace std ...
- 【Java文件操作(五)】从txt文件中读取字符串、乱码原因
我的博客--Java文件操作系列 [Java文件操作(一)]递归打印文件目录 [Java文件操作(二)]删除文件夹,但保留其内部文件 [Java文件操作(三)]递归复制文件夹内所有文件 [Java文件 ...
- 精通lambda表达式:java多核编程_Java8 Lambda表达式和流操作如何让你的代码变慢5倍...
有许许多多关于 Java 8 中流效率的讨论,但根据 Alex Zhitnitsky 的测试结果显示:坚持使用传统的 Java 编程风格--iterator 和 for-each 循环--比 Java ...
- 在Java中使用标准输入输出设备进行字符串,整数浮点数等 的输入输出操作
在Java中使用标准输入输出设备进行字符串.整数浮点数等的输入输出操作 在Java语言中进行标准输入输出(键盘显示器)需要通过创建输入输出流对象的方式进行,一般情况下我们可以使用 BufferedRe ...
- Java Lambda 连接字符串
Java Lambda 连接字符串 public class Menu {/*** 菜品名称*/private String name;/*** 菜品单价*/private Double price; ...
- java中操作字符串都有哪些类,他们之间有什么区别?
java中操作字符串的类有哪些? String StringBuffer StringBuilder 区别 我们可以先看一下这几个类的继承关系图 从类的继承关系上来开的话,String和StringB ...
- java 中操作字符串都有哪些类?它们之间有什么区别?
java 中操作字符串都有哪些类?它们之间有什么区别? String.StringBuffer.StringBuilder String : final修饰,String类的方法都是返回new Str ...
- java 拉姆表达式_Java8 lambda表达式10个示例
Java 8 lambda表达式示例 转自importNew 原文链接 例1.用lambda表达式实现Runnable 我开始使用Java 8时,首先做的就是使用lambda表达式替换匿名类,而实现R ...
- Java 函数式编程和 lambda 表达式
为什么要使用函数式编程 函数式编程更多时候是一种编程的思维方式,是种方法论.函数式与命令式编程的区别主要在于:函数式编程是告诉代码你要做什么,而命令式编程则是告诉代码要怎么做.说白了,函数式编程是基于 ...
最新文章
- windows下安装mongodb步骤
- 【深度学习mmdetection错误】——mmdetection 运行报错KeyError:‘ConvWS is already registered in conv layer‘
- .Net Core3.0依赖注入DI
- LCA求解的四种模板
- python文件操作小总结
- linux中hadoop环境变量配置文件,Ubuntu中关于hadoop环境变量的设置方法
- C#中Redis封装的类
- 易观的大数据革命 分析师与机器人协同办公
- 浅谈SpringMVC之DispatcherServlet
- Android多媒体开发(3)————使用Android NKD编译havlenapetr-FFMpeg-7c27aa2
- php+jq+添加css,jq如何添加css样式?
- 易语言单窗口单ip软件源码_想要挣钱创收 那就用脚本操作手机群控软件啊
- matlab如何修改图例的颜色,在MATLAB图例中设置线条颜色?
- YY淘宝商品数据库设计(转)
- win7桌面背景地址
- Linux云计算架构师:SSHD服务搭建管理和防止暴力破解
- 现货黄金入门:初识心理
- FPGA_PCB 设计之一3.3V-LVTTL与3.3V-LVCMOS区别
- 零基础如何自学编程?用这6种方法就够了!
- 如何获取篮球比赛实时赔率