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))
        {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())
        {throw new PortalException(code,
                "Call CompositeServiceEngine.getCompositeResponse() error, requestClassName:".concat(request.getClass()
                    .getName()));
        }
        else
        {
            M response = apiResult.getData();

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


    default String getCompositeResponseCode(R request)
        throws PortalException
    {

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

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

        int code = apiResult.getCode();
return String.valueOf(code);
    }

}

  这里有3个默认方法,一个抽象方法,抽象方法返回对象ApiResult<M>。我们来看看如果用匿名内部类怎么写:

        CompositeServiceMethodInvoker<GetMyDescResponse, GetMyDescRequest> getMyMethodInvoker =
            new CompositeServiceMethodInvoker<GetMyDescResponse, GetBookFeeDescRequest>(){
    
    public ApiResult<GetMyDescResponse> invoke(InvokeContext context, GetMyDescRequest request)
    {
        ServiceController controller = createRpcController("getMyDesc", context);
        ApiResult<GetMyDescResponse> result = new ApiResult<GetMyDescResponse>(controller);
        stub.getMyDesc(controller, request, result);
        return result;
    }};

  注意这里的泛型已经用具体类型替换了。如果我们使用lambda表达式,那么可以这么写:

        CompositeServiceMethodInvoker<GetMyDescResponse, GetMyDescRequest> getMyMethodInvoker =
            (InvokeContext context, GetBookFeeDescRequest request) -> {
                ServiceController controller = createRpcController("getMyDesc", context);
                ApiResult<GetMyDescResponse> result = new ApiResult<GetMyDescResponse>(controller);
                stub.getMyDesc(controller, request, result);
                return result;
            };

  现在再来看这样一种情况,如果我们刚好在某个类中已经实现了lambda所指代的代码块,比如有这么一个类BookProductConsumer:

public class MyConsumer 
  extends  ServiceConsumer
{

    public ApiResult<GetMyDescResponse> getMyDesc(InvokeContext context,
        GetMyDescRequest request) {
      ServiceController controller = createRpcController("getMyDesc",context);
      ApiResult<GetMyDescResponse> result = new ApiResult<GetMyDescResponse>(controller);
      stub.getMyDesc(controller, request, result);
      return result;
    }
}

  这里的getMyDesc方法返回了ApiResult对象(这里接口里的泛型M已经具体为GetMyDescResponse对象了)。我们可以看到,变量getMyDescMethodInvoker所指代的方法块已经定义在了MyConsumer类的getMyDesc方法中,所以使用方法引用来替换原来的lambda表达式:

CompositeServiceMethodInvoker<GetMyDescResponse, GetMyDescRequest> getMyDescMethodInvoker = MyConsumer::getMyDesc;

  这就是类的方法引用,根据方法调用的不同情况,还有对象的方法引用、类的静态方法引用、类的构造方法引用。

 

posted on 2018-05-29 18:13  不想下火车的人  阅读(1773)  评论(0编辑  收藏  举报

导航