jdk1.8新特性之方法引用


  方法引用其實就是方法調用,符號是兩個冒號::來表示,左邊是對象或類,右邊是方法。它其實就是lambda表達式的進一步簡化。如果不使用lambda表達式,那么也就沒必要用方法引用了。啥是lambda,參見jdk1.8新特性之lambda表達式。看實際例子:

  先看函數式接口:

@FunctionalInterface
public interface CompositeServiceMethodInvoker<M extends Message, R extends Message>
{

    Logger LOGGER = LoggerFactory.getLogger(CompositeServiceMethodInvoker.class);

    ApiResult<M> invoke(InvokeContext ic, R r);

    default M getCompositeResponse(R request)
        throws PortalException
    {
        return getCompositeResponse(GetSpringContext.getInvokeContext(), request);
    }

    default M getCompositeResponse(InvokeContext invokeContext, R request)
        throws PortalException
    {
        if (LOGGER.isDebugEnabled())
        {
            LOGGER.debug(
                "Enter CompositeServiceEngine.getCompositeResponse(), identityId:{}, requestClassName:{}, request:{}",
                CommonHttpUtil.getIdentity(),
                request.getClass().getName(),
                JsonFormatUtil.printToString(request));
        }

        ApiResult<M> apiResult = invoke(invokeContext, request);

        if (Util.isEmpty(apiResult))
        {
            LOGGER.error(
                " CompositeServiceEngine.getCompositeResponse(), Call microservice error, return null, identityId:{}," +
                    " requestClassName:{}, request:{}",
                CommonHttpUtil.getIdentity(),
                request.getClass().getName(),
                JsonFormatUtil.printToString(request));
            throw new PortalException(MSResultCode.MICROSERVICE_RETURN_NULL,
                (" CompositeServiceEngine.getCompositeResponse(), Call microservice error, return null, " +
                    "requestClassName:")
                    .concat(request.getClass().getName()));
        }

        int code = apiResult.getCode();
        if (!apiResult.isSuccess())
        {
            LOGGER.error(
                "Call CompositeServiceEngine.getCompositeResponse() error, identityId:{}, requestClassName:{}, " +
                    "request:{}, return code:{}",
                CommonHttpUtil.getIdentity(),
                request.getClass().getName(),
                JsonFormatUtil.printToString(request),
                code);
            throw new PortalException(code,
                "Call CompositeServiceEngine.getCompositeResponse() error, requestClassName:".concat(request.getClass()
                    .getName()));
        }
        else
        {
            M response = apiResult.getData();

            if (Util.isEmpty(response))
            {
                LOGGER.error(
                    "Call CompositeServiceEngine.getCompositeResponse() error,return null, identityId:{}, " +
                        "requestClassName:{}, request:{}, return code:{}",
                    CommonHttpUtil.getIdentity(),
                    request.getClass().getName(),
                    JsonFormatUtil.printToString(request),
                    code);
                throw new PortalException(code,
                    "Call CompositeServiceEngine.getCompositeResponse() error, return null, requestClassName:".concat(
                        request.getClass().getName()));
            }

            if (LOGGER.isDebugEnabled())
            {
                LOGGER.debug(
                    "Exit CompositeServiceEngine.getCompositeResponse(), identityId:{}, requestClasssName:{}, " +
                        "request:{}, result:{}",
                    CommonHttpUtil.getIdentity(),
                    request.getClass().getName(),
                    JsonFormatUtil.printToString(request),
                    JsonFormatUtil.printToString(response));
            }
            return response;
        }
    }


    default String getCompositeResponseCode(R request)
        throws PortalException
    {
        if (LOGGER.isDebugEnabled())
        {
            LOGGER.debug(
                "Enter CompositeServiceEngine.getCompositeResponse() , identityId:{}, requestClassName:{}, request:{}",
                CommonHttpUtil.getIdentity(),
                request.getClass().getName(),
                JsonFormatUtil.printToString(request));
        }

        ApiResult<M> apiResult = invoke(GetSpringContext.getInvokeContext(), request);

        if (Util.isEmpty(apiResult))
        {
            LOGGER.error(
                " CompositeServiceEngine.getCompositeResponse(), Call microservice error, return null,  " +
                    "identityId:{}, requestClassName:{}, request:{}",
                CommonHttpUtil.getIdentity(),
                request.getClass().getName(),
                JsonFormatUtil.printToString(request));
            throw new PortalException(MSResultCode.MICROSERVICE_RETURN_NULL,
                (" CompositeServiceEngine.getCompositeResponse(), Call microservice error, return null, " +
                    "requestClassName:{}")
                    .concat(request.getClass().getName()));
        }

        int code = apiResult.getCode();

        if (LOGGER.isDebugEnabled())
        {
            LOGGER.debug(
                "Exit CompositeServiceEngine.getCompositeResponse(), identityId:{}, requestClassName:{}, result:{}",
                CommonHttpUtil.getIdentity(),
                request.getClass().getName(),
                code);
        }
        return String.valueOf(code);
    }

}

  這里有3個默認方法,一個抽象方法,抽象方法返回對象ApiResult<M>。我們來看看如果用匿名內部類怎么寫:

        CompositeServiceMethodInvoker<GetBookFeeDescResponse, GetBookFeeDescRequest> getBooFeeDescMethodInvoker =
            new CompositeServiceMethodInvoker<GetBookFeeDescResponse, GetBookFeeDescRequest>(){
    
    public ApiResult<GetBookFeeDescResponse> invoke(InvokeContext context, GetBookFeeDescRequest request)
    {
        ServiceController controller = createRpcController("getBookFeeDesc", context);
        ApiResult<GetBookFeeDescResponse> result = new ApiResult<GetBookFeeDescResponse>(controller);
        stub.getBookFeeDesc(controller, request, result);
        return result;
    }};

  注意這里的泛型已經用具體類型替換了。如果我們使用lambda表達式,那么可以這么寫:

        CompositeServiceMethodInvoker<GetBookFeeDescResponse, GetBookFeeDescRequest> getBooFeeDescMethodInvoker =
            (InvokeContext context, GetBookFeeDescRequest request) -> {
                ServiceController controller = createRpcController("getBookFeeDesc", context);
                ApiResult<GetBookFeeDescResponse> result = new ApiResult<GetBookFeeDescResponse>(controller);
                stub.getBookFeeDesc(controller, request, result);
                return result;
            };

  現在再來看這樣一種情況,如果我們剛好在某個類中已經實現了lambda所指代的代碼塊,比如有這么一個類BookProductConsumer:

public class BookProductConsumer 
  extends  ServiceConsumer
{

    public ApiResult<GetBookFeeDescResponse> getBookFeeDesc(InvokeContext context,
        GetBookFeeDescRequest request) {
      ServiceController controller = createRpcController("getBookFeeDesc",context);
      ApiResult<GetBookFeeDescResponse> result = new ApiResult<GetBookFeeDescResponse>(controller);
      stub.getBookFeeDesc(controller, request, result);
      return result;
    }
}

  這里的getBookFeeDesc方法返回了ApiResult對象(這里接口里的泛型M已經具體為GetBookFeeDescResponse對象了)。我們可以看到,變量getBooFeeDescMethodInvoker所指代的方法塊已經定義在了BookProductConsumer類的getBookFeeDesc方法中,所以使用方法引用來替換原來的lambda表達式:

CompositeServiceMethodInvoker<GetBookFeeDescResponse, GetBookFeeDescRequest> getBooFeeDescMethodInvoker = BookProductConsumer::getBookFeeDesc;

  這就是類的方法引用,根據方法調用的不同情況,還有對象的方法引用、類的靜態方法引用、類的構造方法引用。

 


免責聲明!

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



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