Java 8 实例方法引用等同于 lambda 调用吗?就我而言,它不是

Is Java 8 instance method reference an equivalent to lambda call? In my case it is NOT

我观察到一个非常奇怪的方法引用行为。我们有一个 web 应用程序和 servlet 层次结构链:Servlet A extends Servlet B extends HttpServlet(让我们忽略为什么我们需要这个)。

Web 应用在 Tomcat/Java 8 下托管(web.xml version="3.1" metadata-complete="true")。 在我的本地笔记本电脑上(Tomcat 8.0.35 或 8.5.15,Java 8 更新 131,OSX)我观察到此类 servlet 代码的堆栈溢出:

public class A extends B {
    @Override
    protected void service(HttpServletRequest pRequest, HttpServletResponse pResponse) throws ServletException, IOException {
        ServletCommon.servletServiceWrapper(pRequest, pResponse, super::service);
    }
}

堆栈溢出(见下文)看起来非常可疑 - 它根本不包含层次结构中的 class BClass A 直接调用 HttpServlet(为什么!?这怎么可能!!!????)。

同时使用 lambda 的代码工作正常:

public class A extends B {
    @Override
    protected void service(HttpServletRequest pRequest, HttpServletResponse pResponse) throws ServletException, IOException {
        ServletCommon.servletServiceWrapper(pRequest, pResponse, (t, u) -> super.service(t, u));
    }
}

包装器还包含非常简单的代码:

public class ServletCommon {
    @FunctionalInterface
    public interface MyBiConsumer<T, U>{
        void accept(T t, U u) throws ServletException, IOException ;
    }
public static void servletServiceWrapper(HttpServletRequest request, HttpServletResponse response,
        MyBiConsumer<HttpServletRequest, HttpServletResponse> pDelegate) throws ServletException, IOException {
        pDelegate.accept(request, response);
    }
}

堆栈跟踪

java.lang.WhosebugError
    ServletA.lambda$service[=14=](ServletA.java:19)
    ServletCommon.servletServiceWrapper(ServletCommon.java:31)
    ServletA.service(ServletA.java:19)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    ServletA.lambda$service[=14=](ServletA.java:19)
    ServletCommon.servletServiceWrapper(ServletCommon.java:31)
    ServletA.service(ServletA.java:19)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    ...

有什么想法吗?

Pretty much, yeah.

您设法调用了错误的 service() 方法(public 方法 ServletRequest,而不是受保护的方法 HttpServletRequest),导致无限环形。但是,您的示例代码不够清晰,无法说明发生这种情况的原因。