呵呵,gdy1039 (大勇) 够心细的。
不过你刚好碰到了一块硬骨头,这里的继承关系由于为了能够处理不同的http协议所以引入了handler factory从而变的比较复杂了。呵呵。首先看看
public abstract class URLConnection
extends Object
The abstract class URLConnection is the superclass of all classes that represent a communications link between the application and a URL. Instances of this class can be used both to read from and to write to the resource referenced by the URL. In general, creating a connection to a URL is a multistep process: 
openConnection()                                    connect() 
Manipulate parameters that affect the      Interact with the resource; 
connection to the remote resource.         query header fields and contents. 
                        ----------------------------> 
                                  time
1、The connection object is created by invoking the openConnection method on a URL. 
2、The setup parameters and general request properties are manipulated. 
3、The actual connection to the remote object is made, using the connect method. 
4、The remote object becomes available. The header fields and the contents of the remote object can be accessed. 由此表明真正的连接是openConnection(),这正是URL类的方法。
所以很有趣的是如果你对于协议支持要求不高的话,你完全可以注释掉
// httpUrl.connect();//***这一行***/
而结果基本上不会有什么差别。

解决方案 »

  1.   

    好,接下来我们看看connect()到底做了什么?
    在URL类中,会根据请求来分析到底是什么协议(简单来说http://开头的是http协议,ftp://是ftp协议,如果有兴趣请参考rfc关于url的说明)从而加载相应的实现类,比如http的话,就会实例化"sun.net.www.protocol.http.HttpURLConnection",而那个HttpURLConnection正好就是
    public class HttpURLConnection extends java.net.HttpURLConnection {...}。
    这样就清楚了,connect其实就是sun给出的一个实现罢了。
    一下给出jdk1.5.0中的实现:
        // overridden in HTTPS subclass    public void connect() throws IOException {
    plainConnect();
        }    protected void plainConnect()  throws IOException {
    if (connected) {
        return;
    }
    // try to see if request can be served from local cache
    if (cacheHandler != null && getUseCaches()) {
        try {
    URI uri = ParseUtil.toURI(url);
    if (uri != null) {
        cachedResponse = cacheHandler.get(uri, getRequestMethod(), requests.getHeaders(EXCLUDE_HEADERS));
        if ("https".equalsIgnoreCase(uri.getScheme())
    && !(cachedResponse instanceof SecureCacheResponse)) {
    cachedResponse = null;
        }
        if (cachedResponse != null) {
    cachedHeaders = mapToMessageHeader(cachedResponse.getHeaders());
    cachedInputStream = cachedResponse.getBody();
        }
    }
        } catch (IOException ioex) {
    // ignore and commence normal connection
        }
        if (cachedHeaders != null && cachedInputStream != null) {
    connected = true;
    return;
        } else {
    cachedResponse = null;
        }
    }
    try {
        /* Try to open connections using the following scheme,
         * return on the first one that's successful:
         * 1) if (instProxy != null)
         *        connect to instProxy; raise exception if failed
         * 2) else use system default ProxySelector
         * 3) is 2) fails, make direct connection
         */     if (instProxy == null) { // no instance Proxy is set
    /**
     * Do we have to use a proxy?
     */
    ProxySelector sel = (ProxySelector) 
        java.security.AccessController.doPrivileged( 
         new java.security.PrivilegedAction() {
     public Object run() {
         return ProxySelector.getDefault();
     }
         });
    Proxy p = null;
    if (sel != null) {
        URI uri = sun.net.www.ParseUtil.toURI(url);
        Iterator<Proxy> it = sel.select(uri).iterator();
        while (it.hasNext()) {
    p = it.next();
    try {
        if (!failedOnce) {
    http = getNewHttpClient(url, p, connectTimeout);
    http.setReadTimeout(readTimeout);
        } else {
    // make sure to construct new connection if first
    // attempt failed
    http = getNewHttpClient(url, p, connectTimeout, false);
    http.setReadTimeout(readTimeout);
        }
        break;
    } catch (IOException ioex) {
        if (p != Proxy.NO_PROXY) {
    sel.connectFailed(uri, p.address(), ioex);
    if (!it.hasNext()) {
        // fallback to direct connection
        http = getNewHttpClient(url, null, connectTimeout, false);
        http.setReadTimeout(readTimeout);
        break;
    }
        } else {
    throw ioex;
        }
        continue;
    }
        }
    }
        } else {
    if (!failedOnce) {
        http = getNewHttpClient(url, instProxy, connectTimeout);
        http.setReadTimeout(readTimeout);
    } else {
        // make sure to construct new connection if first
        // attempt failed
        http = getNewHttpClient(url, instProxy, connectTimeout, false);
        http.setReadTimeout(readTimeout);
    }
        }
        
        ps = (PrintStream)http.getOutputStream();
    } catch (IOException e) {
        throw e;
    }
    // constructor to HTTP client calls openserver
    connected = true;
        }
      

  2.   

    HttpURLConnection httpUrl = (HttpURLConnection) targetUrl.openConnection();
    openConnection()是一个工厂方法,targetUrl.openConnection():返回的肯定是一个HttpURLConnection 的具体子类,通过工厂方法就封装了这个具体子类的创建,而只给client一个抽象类。
      

  3.   

    不好意思,写错了一些。
    “...由于为了能够处理不同的http协议所以引入了handler factory从而变的比较复杂了...”
                              ^^^^^^^^^
    应该是URL所支持的不同的协议,http只是其中的一种,呵呵。
      

  4.   

    很多明词都不明白,我看还是需要把基础再打好一点。
    handler factory
    工厂方法
    URI
    这些都不清楚。谢谢版主热情解答,等我明白这个问题后再结这贴子。
      

  5.   

    分析这种代码有意思!不明白:
    在ULR.java中,
    ...
        transient InetAddress hostAddress;    /**
         * The URLStreamHandler for this URL.
         */
        transient URLStreamHandler handler;
    ..."transient"是干什么用的?
      

  6.   

    public final class URL implements java.io.Serializable{...}transient 意思就是序列化或者持久化后由这个关键字修饰的变量将不再被保存,从而变成null或者0。
      

  7.   

    takecare(大厅) ( ) 此人 so强
      

  8.   

    工厂方法解释如下:
    //Generator.java
    public class Generator{
     private int i;
     private Generator(int j){ i=j }
     public Generator getGenerator(int k){     //这个函数就是工厂方法
      return Generator(k);
     }
     public static void main(String[] args){
      ......
     }
    }
    上面的注解的方法就是工厂方法,它的作用是控制对像的产生,使得不是任何人都可以使用NEW产生该对像。URI的解释如下:
    URI是JAVA新加的元素,URL是它的子集。我最近学到的知识就这么多,希望对大家有好处。
    还差handler factory,不知有没有人明白?
      

  9.   

    targetUrl.openConnection()返回了HttpURLConnection子类的对象,因此httpUrl.connect中connect实际是指targetUrl.openConnection实际返回的对象的connect
      

  10.   

    To: lxpbuaa(桂枝香在故国晚秋) 
    你在回答我handler factory的问题?请正面并详细的回答好吗?就这样丢出一堆东西,我们菜菜不一定明的呀,你看看我是一个三角的呀,不像你三个星呀。之前我写的方法有点错,现在改正:
    public class Generator{
     private int i;
     private Generator(int j){ i=j }
     public static Generator getGenerator(int k){     //这个函数就是工厂方法
      return Generator(k);
     }
     public static void main(String[] args){
      ......
     }
    }工厂方法必需是静态的,否则无法调用。
      

  11.   

    我还是不知道handler factory是什么