[CALUG] java code in eclipse: abstract URLConnection

Dave Dodge dododge at dododge.net
Sat Apr 2 00:34:30 EDT 2011


On Tue, Mar 29, 2011 at 05:30:35PM -0700, Walt Smith wrote:
> I read forum where I was trying to figure out why I +can+ make an
> object from an abstract class URLConnection.

You can and you can't.  Of course you can't make one *directly* by
saying:

  new URLConnection(whatever)

because it's an abstract class.  However once you have an instance of
URL, you can use one of its methods to get an instance of some
*unspecified* subclass of URLConnection that does implement the
abstract methods.

> > .....find that the actual implementation of them is found in
> > non-core java classes:
> 
> It was not mentioned what "non-core java classes" meant that I could
> find.

"core" here essentially means the classes that are part of the
standard Java API, such as the ones in java.* subpackages.  Any
particular JVM will also include a bunch of non-standard classes
specific to that JVM implementation, just like any particular C
library will have a bunch of non-standard internal functions for its
own use.

Let's assume we're talking about the Sun/Oracle/OpenJDK
implementation:

> >     URL u = new URL("http://www.google.com");

Inside the URL constructor it grabs the "http" from the front of the
string and constructs a java.net.URLStreamHandler that can handle
"http".  Like URLConnection, URLStreamHandler is also an abstract
class -- but the JVM has internal classes that fully implement it.  In
this particular case they're buried in sun.net.www.protocol.*
subpackages.  The URL class knows about this implementation detail and
so it dynamically loads sun.net.www.protocol.http.Handler.  In the JVM
code that class looks like:

    package sun.net.www.protocol.http;

    public class Handler extends java.net.URLStreamHandler {
        ...non-abstract implementation...
    }

> >     URLConnection uc = u.openConnection();

The URL openConnection method passes the request to the handler's
openConnection method, which here constructs and returns an instance
of sun.net.www.protocol.http.HttpURLConnection -- another class
internal to the JVM:

    package sun.net.www.protocol.http;

    public class HttpURLConnection extends java.net.HttpURLConnection {
        ...non-abstract implementation...
    }

It's a pretty big class -- the OpenJDK 7 version is currently 3300
lines:

    http://hg.openjdk.java.net/jdk7/jdk7/jdk/file/tip/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java

Now if you were to run this same code on some other JVM,
URL.openConnection() would still return an instance of some subclass
of URLConnection but the name of the resulting class and how it's
found may be completely different.

Java is kind of notorious for this sort of abstraction.  Even some
non-abstract classes have no public constructor, and to get an
instance you instead use some other class or call a static method.
java.nio.CharBuffer is an example of this -- to create one you use its
static allocate() method instead of "new".  The Java XML API requires
several layers of this sort of thing.

I sometimes do this in my own classes, for cases where I want
construction to be able to re-use an existing instance, or defer to an
inner/subclass, or perhaps fail by returning a null.  With "new" the
only valid result is a new instance of the exact class asked for and
the only way to fail is by throwing an exception.

                                                  -Dave Dodge




More information about the CALUG mailing list