关于 Java 中向上转换的困惑

Confusion regarding upcasting in Java

我正在 java 中编写网络代码,如下所示:

   //Declaring the reference variable
   HttpsURLConnection httpsURLConnection = null;
   AuthHttpURLConnection authHttpURLConnection = null;

   httpsURLConnection = (HttpsURLConnection) ProxyUrlConnection.openConnection(url);

   httpsURLConnection.setSSLSocketFactory(getSocketFactory());

   authHttpURLConnection = new AuthHttpURLConnection(httpsURLConnection);

我不是 ProxyUrlConnection 和 AuthHttpURLConnection 的作者,但这里是每个的描述:

ProxyURLConnection

public class ProxyURLConnection{
public static synchronized URLConnection openConnection(URL url) throws IOException {
    URLConnection urlConnection = null;
    urlConnection = url.openConnection();
    return urlConnection;
    }
... more stuff
}

AuthHttpURLConnection

public class AuthHttpUrlConnection() extends HttpURLConnection{

public AuthHttpURLConnection(HttpURLConnection connection) {
    super(connection.getURL());
    // sets up the auth headers
}

}

最后HttpURLConnection and HttpsURLConnection

我的具体问题:

  1. 我怎样才能进行这个转换? openConnection returns 一个 URLConnection 的对象,我怎样才能进行这种向下转换而不出现任何运行时错误?

    (HttpsURLConnection) ProxyUrlConnection.openConnection(url);
    
  2. 下面的隐式向上转换是如何工作的?

    AuthHttpURLConnection(httpsURLConnection);
    

    我知道向上转换总是合法的,但如果我这样做,那么实例不是成为 httpURLConnection 而不是 httpsURLConnection 的对象,一旦发生这种情况,我如何能够在 httpURLConnection 的对象上调用方法 setSSLSocketFactory 因为这个方法仅存在于 httpsURLConnection?

一般来说,以下代码有几种可能的运行时流程:



httpsURLConnection = (HttpsURLConnection) ProxyUrlConnection.openConnection(url);
httpsURLConnection.setSSLSocketFactory(getSocketFactory());

  1. 如果传递的 url 参数有 'https://' 方案,那么它应该可以正常工作。
  2. 如果传递的 url 以任何其他方案开始(例如 'http://'、'ftp://'),则 ProxyUrlConnection.openConnection(url); 可能 return 的不同实现URLConnection(例如 HttpURLConnectionJarURLConnection),那么您的代码仍将编译,但是,在应用程序运行期间,您将得到一个 ClassCastException,这将阻止流程的进一步执行(因此提出您的问题:URLConnection 的其他实现实际上永远不会调用 setSSLSocketFactory

只要您明确验证此处理流程之前的 https:// 方案,就可以使用该代码段,否则您必须明确处理 [=14 的不同实现时的情况=] 被 return 编辑以防止 ClassCastException.

长话短说:

How am I able to do this casting? openConnection returns an object of URLConnection, how can I do this downcasting and not get any runtime errors?

只要您有显式转换,这段代码就会编译。但是,如果 URLConnection 的任何其他实现被 returned 除了 HttpsURLConnection

,它将在应用程序运行时以 ClassCastException 失败

How I am able to call a method setSSLSocketFactory on an object of httpURLConnection since this method is only present in httpsURLConnection?

如果提供了非 'https' URI(参见上一点),应用程序执行流程将在到达 setSSLSocketFactory 方法调用之前失败 ClassCastException

How is the following implicit upcasting working?

AuthHttpURLConnection(httpsURLConnection); 只要应用程序流达到这一点,这个隐式转换将始终有效,这将确保 connection 是 [= 的任何子类的实例15=] 否则 ClassCastException 会在那之前被抛出(见前面的 2 点)

希望对您有所帮助。