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就可以获得属性信息。

posted @ 2020-09-04 23:30  strongmore  阅读(1718)  评论(0编辑  收藏  举报