I am writing a networking code in java and It looks like following:
//Declaring the reference variable
HttpsURLConnection httpsURLConnection = null;
AuthHttpURLConnection authHttpURLConnection = null;
httpsURLConnection = (HttpsURLConnection) ProxyUrlConnection.openConnection(url);
httpsURLConnection.setSSLSocketFactory(getSocketFactory());
authHttpURLConnection = new AuthHttpURLConnection(httpsURLConnection);
I am not the author of ProxyUrlConnection and AuthHttpURLConnection but here is a description of each:
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
}
}
And finally HttpURLConnection and HttpsURLConnection
My specific questions:
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?
(HttpsURLConnection) ProxyUrlConnection.openConnection(url);
How is the following implicit upcasting working?
AuthHttpURLConnection(httpsURLConnection);
I know upcasting is always legal but if I do this then isn't the instance become an object of httpURLConnection instead of httpsURLConnection and once that happen how I am able to call a method setSSLSocketFactory on an object of httpURLConnection since this method is only present in httpsURLConnection?
Generally speaking there are couple of possible runtime flows for the following code :
httpsURLConnection = (HttpsURLConnection) ProxyUrlConnection.openConnection(url);
httpsURLConnection.setSSLSocketFactory(getSocketFactory());
url
parameter has 'https://' scheme then it should work without any problems.url
starts with any other scheme (eg. 'http://', 'ftp://') then ProxyUrlConnection.openConnection(url);
might return a different implementation of the URLConnection
(eg HttpURLConnection
, JarURLConnection
) then your code will still compile, however, during the application runtime you will get a ClassCastException
which will prevent the further execution of the flow (hence coming to your question : setSSLSocketFactory
will never be actually called for the other implementations of the URLConnection
)It is fine to use that snippet as long as you have an explicit validation for the https://
scheme preceding this processing flow, otherwise you have to explicitly deal with the cases when a different implementation of URLConnection
is returned to prevent a ClassCastException
.
Long story short :
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?
As long you have explicit casting then this code will compile. However, it will fail during the application runtime with ClassCastException
if any other implementation of URLConnection
is returned except HttpsURLConnection
How I am able to call a method setSSLSocketFactory on an object of httpURLConnection since this method is only present in httpsURLConnection?
Application execution flow will fail with ClassCastException
prior reaching the setSSLSocketFactory
method call if non 'https' URI is provided (see previous point)
How is the following implicit upcasting working?
AuthHttpURLConnection(httpsURLConnection);
this implicit cast will always work as long as application flow reached this point which would have been insured that the connection
is an instance of any subclass of HttpURLConnection
otherwise ClassCastException
would have been thrown prior to that point (see previous 2 points)
Hope this helps.