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 B! Class 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
),导致无限环形。但是,您的示例代码不够清晰,无法说明发生这种情况的原因。
我观察到一个非常奇怪的方法引用行为。我们有一个 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 B! Class 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
),导致无限环形。但是,您的示例代码不够清晰,无法说明发生这种情况的原因。