为什么从超级到子接口的这种转换有效?

时间:2015-01-16 19:31:15

标签: java servlets

我正在从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;

我理解从ServletResponseHttpServletResponse的演员表是必要的,因为后一个界面有#setHeader()。但为什么这个演员会工作呢?它是否有效,因为传递给方法的基础对象是HttpServletResponse

但是除了运行时,编译器为什么允许这样做?我是Java的新手,并且预计这个演员会失败,因为它是从一个更少到更具体的类型。例如,使用ElementVertex,我失败了:

Vertex v = (Vertex) e; // `e` is an `Element`

1 个答案:

答案 0 :(得分:4)

The JLS几乎完全解释了它。

  

5.1.6缩小参考转换

     

此类转换需要在运行时进行测试,以确定实际参考值是否是新类型的合法值。如果不是,则抛出ClassCastException。

即。当你进行这样的转换时,类型S明确地转换为类型T.通过这样做,你告诉编译器"我确信这没关系"。

如果您认为可能失败,那么您应try...catch ClassCastException并停止您的程序意外终止。