【问题标题】:Why does SSLSocketFactory.createSocket returns a Socket instead of SSLSocket?为什么 SSLSocketFactory.createSocket 返回的是 Socket 而不是 SSLSocket?
【发布时间】:2013-08-16 02:44:33
【问题描述】:

在我的代码中,根据一个布尔标志,我应该决定是否与 SSL 套接字握手。我使用 SSLSocketFactory 创建套接字,这是从官方 Javadoc 中获取的 createSocket 方法的签名。

abstract Socket createSocket(Socket s, String host, int port, boolean autoClose)

在这里返回Socket 而不是SSLSocket 似乎是一个明确的设计选择,这意味着使用此方法的类不需要知道SocketSSLSocket

但是,如果我必须握手,我必须向下转换它,因为方法

  public abstract void startHandshake() throws java.io.IOException;

在 SSLSocket 类上定义。

SSLSocket socket = (SSLSocket) SSLSocketFactory.getDefault().createSocket( getApiServerAddress(), getPort() );

三个可能的答案中哪个是正确的?

  • 库中的这种设计模式表明您不应该直接调用 startHandShake(),而是调用 Socket 类上的某个方法,该方法将调用 startHandShake()。 Socket 类的这个方法是什么?而且,如果是这样,为什么 startHandShake() 是公开的?

  • 库设计不佳。

  • 我没有以正确的方式创建 SSLSocket。

【问题讨论】:

    标签: java jsse


    【解决方案1】:

    因为createSocket 方法继承自SocketFactory。无法覆盖结果类型。

    可能有一种使用泛型的方法,但这会破坏现有的 API 和所有现有的代码。

    【讨论】:

    • 您可以使用子类覆盖结果类型。这称为协变返回 - stackoverflow.com/questions/10134571/…。但是它只在 Java 1.5 中引入,所以可能 SSLSocketFactory 是在那之前设计的
    • @boky 它不会破坏现有代码 - 您始终可以在需要超类型的地方传递子类型(并且实际运行时类型始终相同,即使使用旧方法签名)
    • @artbristol 不,它不会编译时间,我同意。不过,我不太确定已经编译的代码。
    • @artbristol 但是签名改变时至少有NoSuchMethodError的风险。
    • @artbristol 从技术上改变返回类型产生NoSuchMethodError。它只是发生在我身上。试试看。
    猜你喜欢
    • 1970-01-01
    • 2010-12-16
    • 2014-04-09
    • 1970-01-01
    • 2015-11-02
    • 2021-09-13
    • 2017-06-30
    • 1970-01-01
    相关资源
    最近更新 更多