为什么这种从超级接口到子接口的转换有效?
Why does this casting from a super to a sub-interface work?
我正在从 Spring Boot guide:
看这个例子
@Component
public class SimpleCORSFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
chain.doFilter(req, res);
}
public void init(FilterConfig filterConfig) {}
public void destroy() {}
我对这一行感到困惑:
HttpServletResponse response = (HttpServletResponse) res;
我理解从 ServletResponse
到 HttpServletResponse
的转换是必要的,因为后一个接口有 #setHeader()
。但是为什么这个演员表有效?是否因为传递给该方法的基础对象是 HttpServletResponse
而起作用?
但是除了运行时之外,为什么编译器允许这样做?我是 Java 的新手,并且预计此转换会失败,因为它是从不太具体的类型到更具体的类型。例如,使用 Element and Vertex,我遇到了这个失败:
Vertex v = (Vertex) e; // `e` is an `Element`
The JLS 几乎完美地解释了它。
5.1.6 Narrowing Reference Conversion
Such conversions require a test at run time to find out whether the actual reference value is a legitimate value of the new type. If not, then a ClassCastException is thrown.
即当您进行此类转换时,您 明确地将类型 S 转换为类型 T。这样做是在告诉编译器“我确定这是可以的”。
如果您认为它 可能 失败,那么您应该 try...catch
ClassCastException
并停止您的程序意外终止。
我正在从 Spring Boot guide:
看这个例子@Component
public class SimpleCORSFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
chain.doFilter(req, res);
}
public void init(FilterConfig filterConfig) {}
public void destroy() {}
我对这一行感到困惑:
HttpServletResponse response = (HttpServletResponse) res;
我理解从 ServletResponse
到 HttpServletResponse
的转换是必要的,因为后一个接口有 #setHeader()
。但是为什么这个演员表有效?是否因为传递给该方法的基础对象是 HttpServletResponse
而起作用?
但是除了运行时之外,为什么编译器允许这样做?我是 Java 的新手,并且预计此转换会失败,因为它是从不太具体的类型到更具体的类型。例如,使用 Element and Vertex,我遇到了这个失败:
Vertex v = (Vertex) e; // `e` is an `Element`
The JLS 几乎完美地解释了它。
5.1.6 Narrowing Reference Conversion
Such conversions require a test at run time to find out whether the actual reference value is a legitimate value of the new type. If not, then a ClassCastException is thrown.
即当您进行此类转换时,您 明确地将类型 S 转换为类型 T。这样做是在告诉编译器“我确定这是可以的”。
如果您认为它 可能 失败,那么您应该 try...catch
ClassCastException
并停止您的程序意外终止。