use*_*361 2 java eclipse extends
嗨,我正在尝试深入学习JAVA,所以我在以下几行中深入研究JDK源代码:
URL url = new URL("http://www.google.com");
URLConnection tmpConn = url.openConnection();
Run Code Online (Sandbox Code Playgroud)
我附加了源代码并在第二行设置断点并进入代码.我可以看到代码流是:URL.openConnection() - > sun.net.www.protocol.http.Handler.openConnection()我对此有两个问题
首先在URL.openConnection()中,代码是:
public URLConnection openConnection() throws java.io.IOException {
return handler.openConnection(this);
}
Run Code Online (Sandbox Code Playgroud)
handler是URLStreamHandler的一个对象,定义为blow
transient URLStreamHandler handler;
Run Code Online (Sandbox Code Playgroud)
但是URLStreamHandler是一个抽象类,方法openConnection()没有在其中实现,所以当handler调用这个方法时,它应该去找一个实现这个方法的子类,对吧?但是有很多类在sun.net.www.protocol中实现这些方法(如http.Hanlder,ftp.Handler)代码应该如何知道它应该调用哪个"openConnection"方法?在这个例子中,这个handler.openConnection()将进入http.Handler并且它是正确的.(如果我将网址设置为ftp://www.google.com,则会进入ftp.Handler)我无法理解该机制.
第二.我已经附加了源代码,所以我可以进入JDK并查看变量,但对于许多类,如sun.net.www.protocol.http.Handler,src.zip中没有源代码.我用谷歌搜索了这个类,我可以在线获取源代码,但为什么他们没有把它(以及许多其他类)放在src.zip中?我在哪里可以找到全面的源代码版本?
谢谢!
首先是简单的部分:
...我google了这个类,我可以在线获取源代码,但为什么他们没有把它(以及许多其他类)放在src.zip中?
两个原因:
在Java代码库是专有的过去,这被视为秘密...并且不包括在内src.zip.当他们在GPL下重新许可Java 6时,他们并没有费心去改变它.(不知道为什么.问问Oracle.)
因为sun.*树中的任何代码都是正式的"实现细节,如有更改,恕不另行通知".如果他们提供直接的过程中,它可以帮助客户忽略的建议,并可能导致更多的摩擦/坏消息时,客户代码的假期,因为在未经宣布的变化的结果sun.*代码.
我在哪里可以找到全面的源代码版本?
您可以在OpenJDK 6/7/8存储库和相关的下载包中找到它:
现在关于"深入学习Java"的部分.
首先,我认为你可能会以"次优"的方式进行这种学习.我认为您应该阅读有关Java和设计模式以及为自己编写代码的书籍,而不是阅读Java类库.
具体如下:
但是
URLStreamHandler抽象类和方法openConnection()是没有实现的,所以当处理程序调用这个方法时,它应该去找一个实现这个方法的子类,对吧?
在处理程序调用而不是方法时,它在子类的实例上调用它.因此,找到正确的方法由JVM处理......就像任何其他多态分派一样.
棘手的部分是如何获得sun.net.www.protocol.*处理程序类的实例.这发生的事情是这样的:
创建URL对象时,它会调用getURLStreamHandler(protocol)以获取处理程序实例.
此方法的代码查看协议的处理程序实例是否已存在,如果存在,则返回该实例.
否则,它会查看协议处理程序工厂是否存在,如果存在,则使用它来创建处理程序实例.(协议处理程序工厂对象可以由应用程序设置.)
否则,搜索可配置的Java包列表以查找其FQN所在的类package + "." + protocol + "." + "Handler",加载它,并使用反射来创建实例.(配置是通过系统属性.)
对处理程序的引用存储在URL的处理程序字段中,并且URL构造继续.
因此,稍后,当您调用openConnection()URL对象时,该方法使用Handler特定于该协议的实例URL来创建连接对象.
这个复杂过程的目的是支持开放式协议集的URL连接,允许应用程序为新协议提供处理程序,并静态和动态地用自己的处理程序替换现有协议.(而且代码比我上面描述的更复杂,因为它必须处理多个线程.)
这是利用许多设计模式(缓存,适配器,工厂对象等)以及Java特定的东西,如系统属性和反射.但是如果你还没有阅读和理解那些设计模式,等等,你就不太可能认出它们,因此你很可能会发现代码完全不同.因此我的建议是:首先学习基础知识!!
| 归档时间: |
|
| 查看次数: |
916 次 |
| 最近记录: |