sinat_29621543
自自然卷
采纳率35.7%
2016-12-08 13:28 阅读 1.2k
已采纳

Java openConnection问题

2
URL url = new URL("http://www.sina.com.cn");
HttpURLConnection urlConnection = (HttpURLConnection) (url.openConnection());

上面第二句中url.openConnection调用的不是URLStreamHandler里的抽象函数openConnection吗
我找不到有哪个子类实现了openConnection,想问哪个子类实现了openConnection?
谢谢!

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

2条回答 默认 最新

  • 已采纳
    Readiay Readiay 2016-12-09 02:05

    我来给你找一下,首先你点开url.openConnection();

         public URLConnection openConnection() throws java.io.IOException {
            return handler.openConnection(this);
        }
    

    你发现这里是handler调用的,但是这个handler是怎么赋值的呢?于是你就需要找哪里初始化了这个handler

    在java里面,初始化一个对象,要么静态代码块,要么就是构造器里面,于是现在我们点进去URL那个构造器里面

     public URL(URL context, String spec, URLStreamHandler handler)
            throws MalformedURLException
    

    经过层层点击,最终调用的是方法签名是如上的这个类,于是你就看那个handler,哪里出现了,哪里初始化了

                 // Get the protocol handler if not specified or the protocol
                // of the context could not be used
                if (handler == null &&
                    (handler = getURLStreamHandler(protocol)) == null) {
                    throw new MalformedURLException("unknown protocol: "+protocol);
                }
    
                this.handler = handler;
    

    你就随便看几眼,你就能看到这里是赋值了,然后你还发现上面if条件里面有个判断,就是如果handler == null,
    就调用了getURLStreamHandler()这个方法,点进去

    图片说明

    你会发现这里有一个工厂,如果这个协议没有得到handler就从工场里面获取handler。点进去看看

     private static class Factory implements URLStreamHandlerFactory {
            private static String PREFIX = "sun.net.www.protocol";
    
            public URLStreamHandler createURLStreamHandler(String paramString) {
                String str = PREFIX + "." + paramString + ".Handler";
                try {
                    Class localClass = Class.forName(str);
                    return ((URLStreamHandler) localClass.newInstance());
                } catch (ClassNotFoundException localClassNotFoundException) {
                    localClassNotFoundException.printStackTrace();
                } catch (InstantiationException localInstantiationException) {
                    localInstantiationException.printStackTrace();
                } catch (IllegalAccessException localIllegalAccessException) {
                    localIllegalAccessException.printStackTrace();
                }
                throw new InternalError("could not load " + paramString + "system protocol handler");
            }
        }
    

    这里你就会发现,他使用字符串拼凑的方式,产生一个类的路径,于是你想找的那个类就是在

    sun.net.www.protocol.http.Handler 就是这个类

    这里多次出现了protocol, 这个是什么呢?

    比如说:http://www.baidu.com ftp://192.168.133.100
    https://www.baidu.com

    这个URL长的都蛮像的,其实这个protocol、就是前面的http,https,ftp等
    表示使用什么通信协议。

    所以你就会发现,如果你使用的是ftp开头的,那么这个handler就是

    sun.net.www.protocol.ftp.Handler

    如果你觉得答得不错,就采纳吧

    点赞 评论 复制链接分享
  • qq381332153 noWayBinding 2016-12-09 02:20

    看别人分析那么多,不如自己打一个断点,DEBUG一步步走下去看个究竟。这样印象深刻

    点赞 评论 复制链接分享