gpt4 book ai didi

eclipse - 不懂JAVA中URL.openConnection()中extends的概念

转载 作者:行者123 更新时间:2023-12-02 07:05:25 24 4
gpt4 key购买 nike

您好,我正在尝试深入学习 JAVA,因此我正在深入研究 JDK 源代码中的以下几行:

URL url = new URL("http://www.google.com");
URLConnection tmpConn = url.openConnection();

我附上源码,在第二行设置断点,单步执行代码。我可以看到代码流是: URL.openConnection() -> sun.net.www.protocol.http.Handler.openConnection()我有两个问题

首先在 URL.openConnection() 中的代码是:

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

handler是URLStreamHandler的一个对象,定义如下

transient URLStreamHandler handler;

但是URLStreamHandler是一个抽象类,并没有在其中实现openConnection()方法,所以当handler调用这个方法的时候,它应该去找一个实现这个方法的子类,对吧?但是在 sun.net.www.protocol 中有很多实现这个方法的类(比如 http.Hanlder, ftp.Handler )代码应该如何知道它应该调用哪个“openConnection”方法?在这个例子中,这个 handler.openConnection() 将进入 http.Handler 并且它是正确的。 (如果我将 url 设置为 ftp://www.google.com,它将进入 ftp.Handler)我无法理解该机制。

第二个。我附上了源代码,这样我就可以进入 JDK 并查看变量,但是对于许多类,如 sun.net.www.protocol.http.Handler,src.zip 中没有源代码。我用谷歌搜索了这个类(class),我可以在网上找到源代码,但为什么他们没有把它(和许多其他类(class))放在 src.zip 中?哪里可以找到完整版的源码?

谢谢!

最佳答案

首先是简单的部分:

... I googled this class and there is source code online I can get but why they did not put it (and many other classes) in the src.zip?

两个原因:

  • 在过去 Java 代码库是专有的,这被视为 secret ...并且不包含在 src.zip 中。当他们在 GPL 下重新授权 Java 6 时,他们没有费心去改变它。 (不知道为什么。问Oracle。)

  • 因为 sun.* 树中的任何代码都是正式的“实现细节如有更改,恕不另行通知”。如果他们直接提供代码,则可以帮助客户忽略该建议。当客户代码由于对 sun.* 代码的未经宣布的更改而中断时,这可能会导致更多的摩擦/负面报道。

Where can I find a comprehensive version of source code?

您可以在 OpenJDK 6/7/8 存储库和相关下载包中找到它:


现在是关于“深入学习Java”的部分。

首先,我认为您可能正在以“次优”方式进行此学习。我认为您应该阅读有关 Java 和设计模式的书籍并自己编写代码,而不是阅读 Java 类库。

具体情况:

But URLStreamHandler is a abstract class and method openConnection() is not implement in it so when handler calls this method, it should go to find a subclass who implement this method, right?

在处理程序调用 than 方法时,它是在子类的实例上调用它。因此,找到正确的方法由 JVM 处理……就像任何其他多态调度一样。

棘手的部分是如何获得 sun.net.www.protocol.* 处理程序类的实例。发生这样的事情:

  1. 创建 URL 对象时,它会调用 getURLStreamHandler(protocol) 来获取处理程序实例。

  2. 此方法的代码查看协议(protocol)的处理程序实例是否已存在,如果存在则返回。

  3. 否则,它会查看协议(protocol)处理程序工厂是否存在,如果存在,它会使用它来创建处理程序实例。 (协议(protocol)处理程序工厂对象可以由应用程序设置。)

  4. 否则,搜索可配置的 Java 包列表以查找 FQN 为 package + "."的类。 +协议(protocol)+“。” + "Handler",加载它,并使用反射创建一个实例。 (通过系统属性进行配置。)

  5. 对处理程序的引用存储在 URL 的处理程序字段中,并且 URL 构造继续进行。

因此,稍后,当您在 URL 对象上调用 openConnection() 时,该方法使用特定于 协议(protocol)的 Handler 实例用于创建连接对象的 URL

这个复杂过程的目的是支持开放式协议(protocol)集的 URL 连接,允许应用程序为新协议(protocol)提供处理程序,并以静态和动态方式替换现有协议(protocol)的自己的处理程序。 (而且代码比我上面描述的更复杂,因为它必须处理多个线程。)

这利用了许多设计模式(缓存、适配器、工厂对象等)以及 Java 特定的东西,例如系统属性和反射。但是,如果您没有阅读和理解这些设计模式等,您就不太可能认出它们,因此您可能会发现代码完全是糊涂的。因此我上面的建议是:先学习基础知识!!

关于eclipse - 不懂JAVA中URL.openConnection()中extends的概念,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12764764/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com