@FunctionalInterface 函数式编程原理

用法

  • Object::get(),"test"
  • obj::get()
  • 常用于动态查询

定义

  • @FunctionalInterface 接口仅为了辅助编译器识别,该接口有没有均可
  • 定义的接口只能有一个抽象方法,允许有N个default方法 (N>=0)
  • 当抽象方法带参数时,Lambda语法为(Object::get(),"test") 类定义
  • 当抽象方法不带参数时, Lambda 语法为 (obj::get()) 类实例

原理

  • 该接口jvm会内置一个 writeReplace 方法
  • writeReplace 是私有的
  • 此方法会返回 SerializedLambda 对象

代码实例

定义接口

@FunctionalInterface
public interface TestFunction extends Serializable {

    /**
     * get() 不带参  带参 传实例 obj::方法
     * get(Object obj) 传类定义 Object::方法
     *
     * @return
     */
    Object get();

    //这个方法返回的SerializedLambda是重点
    default SerializedLambda getSerializedLambda() throws Exception {
        //writeReplace改了好像会报异常
        Method write = this.getClass().getDeclaredMethod("writeReplace");
        write.setAccessible(true);
        return (SerializedLambda) write.invoke(this);
    }
}

定义方法传参

public static void eq(TestFunction... functions) throws Exception {
        for (TestFunction function : functions) {
            SerializedLambda serializedLambda = function.getSerializedLambda();
            String implMethodName = serializedLambda.getImplMethodName();
            String paramName = resolveFieldName(implMethodName);
            System.out.println(String.format("参数名:%s 参数值:%s", paramName, function.get()));
        }
    }


/**
     * 

* 解析 getMethodName -> propertyName *

* * @param getMethodName 需要解析的 * @return 返回解析后的字段名称 */ public static String resolveFieldName(String getMethodName) { if (getMethodName.startsWith("get")) { getMethodName = getMethodName.substring(3); } else if (getMethodName.startsWith("is")) { getMethodName = getMethodName.substring(2); } // 小写第一个字母 return firstToLowerCase(getMethodName); } /** *

* 首字母转换小写 *

* * @param param 需要转换的字符串 * @return 转换好的字符串 */ public static String firstToLowerCase(String param) { if (StringUtils.isBlank(param)) { return ""; } return param.substring(0, 1).toLowerCase() + param.substring(1); }

调用方法

   public static void main(String[] args) throws Exception {
        SellingDO sellingDO = new SellingDO();
        sellingDO.setId(123L);
        sellingDO.setSellingName("test");
        eq(sellingDO::getId, sellingDO::getSellingName);
    }

你可能感兴趣的:(@FunctionalInterface 函数式编程原理)