一、
(1)获取Lambda表达式来自于哪个类的..
Java8 lambda函数接口如果继承了Serializable这个接口,
那么把lambda函数的实例对象序列化成字节,然后再使用ObjectInputStream反序列化成一个对象,
此时反序列化获得的对象是SerializedLambda类型的一个实例,
通过这个SerializedLambda实例对象,可以获取到lambda表达式是由哪个类调用过来的。
(2)例子:
比如A::getB这个lambda表达式,
底层接收的函数接口是继承了Serializable接口的话,比如Mybatis-plus的SFunction函数接口。
每次传入A::getB这个方法引用作为参数给SFunction接口时,底层都是创建一个SFunction的实例对象,这个对象封装了对A的getB方法的调用。
通过上述序列化再反序列化后的SerializedLambda对象,可以从中获取到这个lambda表达式的实例是由A这个类获取的,也就是说,可以拿到A的Class<A>对象。
具体参考方法:(自己新建一个类似的接口,SFunction同时继承了Serializable接口)
com.baomidou.mybatisplus.core.toolkit.LambdaUtils#resolve
测试代码如下:
public static void main(String[] args) throws Exception {
SFunction<A,?> fn =A::getB;
Method method = fn.getClass().getDeclaredMethod("writeReplace");
method.setAccessible(Boolean.TRUE);
SerializedLambda serializedLambda = (SerializedLambda) method.invoke(fn);
System.out.println("方法引用来源的类的全限定名为:"+serializedLambda.getImplClass());
System.out.println("方法引用来源的方法名:" + serializedLambda.getImplMethodName());
}
static class A{
private B b;
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
}
static class B{}
@FunctionalInterface
public interface SFunction<T,R> extends Serializable {
R apply(T t);
}
输出结果为:
方法引用来源的类的全限定名为:Main$A
方法引用来源的方法名:getB