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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM