SerializedLambda
在java 8中,如果函数式接口实现了Serializable,那这个函数式接口用lambda表达式实现时,编译后的函数式接口的实现类,会有一个私有的“writeReplace”方法,返回 SerializedLambda 对象。而 SerializedLambda 这个类,包含了函数式接口和实现方法等的信息。 方法:
- serializedLambda.getImplMethodName(),获取实现方法的名称。如果是直接传递的方法引用,则获取的就是引用的方法的名称
- serializedLambda.getImplClass(),获取实现方法所在的类的全限定名,用过“/”连接的字符串。如果是直接传递的方法引用,就能获取引用的方法所在类的名称
实现了Serializable接口的Function函数
@FunctionalInterface
public interface SFunction<T, R> extends Function<T, R>, Serializable {
}
package com.fxin.lambda;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class FieldUtil {
/**
* 将bean的属性的get方法,作为lambda表达式传入时,获取get方法对应的属性Field
*
* @param fn lambda表达式,bean的属性的get方法
* @param <T> 泛型
* @return 属性对象
*/
public static <T> Field getField(SFunction<T, ?> fn) {
// 从function取出序列化方法
Method writeReplaceMethod;
try {
writeReplaceMethod = fn.getClass().getDeclaredMethod("writeReplace");
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
// 从序列化方法取出序列化的lambda信息
boolean isAccessible = writeReplaceMethod.isAccessible();
writeReplaceMethod.setAccessible(true);
SerializedLambda serializedLambda;
try {
serializedLambda = (SerializedLambda) writeReplaceMethod.invoke(fn);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
} finally {
writeReplaceMethod.setAccessible(isAccessible);
}
// 从lambda信息取出method、field、class等
String implMethodName = serializedLambda.getImplMethodName();
// 确保方法是符合规范的get方法,boolean类型是is开头
if (!implMethodName.startsWith("is") && !implMethodName.startsWith("get")) {
throw new RuntimeException("get方法名称: " + implMethodName + ", 不符合java bean规范");
}
// get方法开头为 is 或者 get,将方法名 去除is或者get,然后首字母小写,就是属性名
int prefixLen = implMethodName.startsWith("is") ? 2 : 3;
String fieldName = implMethodName.substring(prefixLen);
String firstChar = fieldName.substring(0, 1);
fieldName = fieldName.replaceFirst(firstChar, firstChar.toLowerCase());
Field field;
try {
field = Class.forName(serializedLambda.getImplClass().replace("/", ".")).getDeclaredField(fieldName);
} catch (ClassNotFoundException | NoSuchFieldException e) {
throw new RuntimeException(e);
}
return field;
}
}
被测试对象
package com.fxin.netty.entity;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;
/**
*
* This class was generated by MyBatis Generator.
* This class corresponds to the database table user
*/
@Table(name="user")
public class UserEntity {
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column user.id
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
@Id
private String id;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column user.username
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
private String username;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column user.password
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
private String password;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column user.face_image
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
@Column(name = "face_image")
private String faceImage;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column user.face_image_big
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
@Column(name = "face_image_big")
private String faceImageBig;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column user.nick_name
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
private String nickName;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column user.qrcode
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
private String qrcode;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column user.cid
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
private String cid;
private Date currentDate;
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column user.id
*
* @return the value of user.id
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
public String getId() {
return id;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column user.id
*
* @param id the value for user.id
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
public void setId(String id) {
this.id = id == null ? null : id.trim();
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column user.username
*
* @return the value of user.username
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
public String getUsername() {
return username;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column user.username
*
* @param username the value for user.username
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
public void setUsername(String username) {
this.username = username == null ? null : username.trim();
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column user.password
*
* @return the value of user.password
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
public String getPassword() {
return password;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column user.password
*
* @param password the value for user.password
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
public void setPassword(String password) {
this.password = password == null ? null : password.trim();
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column user.face_image
*
* @return the value of user.face_image
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
public String getFaceImage() {
return faceImage;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column user.face_image
*
* @param faceImage the value for user.face_image
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
public void setFaceImage(String faceImage) {
this.faceImage = faceImage == null ? null : faceImage.trim();
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column user.face_image_big
*
* @return the value of user.face_image_big
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
public String getFaceImageBig() {
return faceImageBig;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column user.face_image_big
*
* @param faceImageBig the value for user.face_image_big
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
public void setFaceImageBig(String faceImageBig) {
this.faceImageBig = faceImageBig == null ? null : faceImageBig.trim();
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column user.nick_name
*
* @return the value of user.nick_name
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
public String getNickName() {
return nickName;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column user.nick_name
*
* @param nickName the value for user.nick_name
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
public void setNickName(String nickName) {
this.nickName = nickName == null ? null : nickName.trim();
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column user.qrcode
*
* @return the value of user.qrcode
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
public String getQrcode() {
return qrcode;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column user.qrcode
*
* @param qrcode the value for user.qrcode
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
public void setQrcode(String qrcode) {
this.qrcode = qrcode == null ? null : qrcode.trim();
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column user.cid
*
* @return the value of user.cid
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
public String getCid() {
return cid;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column user.cid
*
* @param cid the value for user.cid
*
* @mbg.generated Wed Nov 24 22:37:18 CST 2021
*/
public void setCid(String cid) {
this.cid = cid == null ? null : cid.trim();
}
public Date getCurrentDate() {
return currentDate;
}
public void setCurrentDate(Date currentDate) {
this.currentDate = currentDate;
}
}
测试类
package com.fxin.lambda;
import com.fxin.netty.entity.UserEntity;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import static com.fxin.lambda.FieldUtil.*;
public class TestLambda {
public static void main(String[] args) {
Field field = getField(UserEntity::getCurrentDate);
System.out.println(field);
// 字段名称
String fieldName = field.getName();
System.out.println(fieldName);
// 字段上面的注解
Annotation[] annotations = field.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
// 字段的类型
Class<?> type = field.getType();
System.out.println(type);
}
}