java - 在构造函数中调用可重写的方法是不好的。有异常(exception)吗?

标签 java constructor overriding abstract-class convention

我想知道在某些情况下,如果有足够的方法意图文档,在抽象类的构造函数中调用 public 方法或在这种情况下,特别是调用 protected 方法是可以的,或者至少是可以原谅的。

我的实际问题涉及一个抽象类 IdentifiedConnection,如下所示:

public abstract class IdentifiedConnection extends Connection {

    private UUID uuid;

    public IdentifiedConnection(String serverAddress, int port) throws IOException {
        super(serverAddress, port);
        this.uuid = this.aquireIdentifier();
    }

    public UUID getIdentifier() {
        return this.uuid;
    }

    protected abstract UUID aquireIdentifier() throws IOException;

}

我的目的是从服务器获取一个 UUID 标识符。如果服务器以有效的 UUID 响应,我们将在此类的字段中设置该 UUID(名为 uuid)。如果服务器响应非 UUID 消息,我们假设服务器由于某种原因无法访问并抛出 IOException

一般来说,我知道从构造函数调用可重写的方法是不好的,因为它会使类容易出现各种或多或少难以检测的错误。但是,在这种情况下,我觉得这样做实际上并不算太糟糕(只要我用 javadoc 搞定它)。

你有什么想法?这仍然是一个非常糟糕的主意吗?如果您认为这样做不好,您建议采用哪种替代方法?


我已将 Connection 类的代码留在这个问题之外,因为我认为它不相关。

最佳答案

在这种情况下,我建议您使用工厂方法。

写一个静态方法调用类似的东西

public static IdentifiedConnection openConnection(String serverAddress, int port)
        throws IOException {
    ...
}

这允许更好地控制创建并避免泄漏对未初始化对象的引用的潜在问题。


另一种方法是采用 Supplier<UUID>作为构造函数的参数,如下所示:

abstract class IdentifiedConnection extends Connection {

    private UUID uuid;

    public IdentifiedConnection(String serverAddress,
                                int port,
                                Supplier<UUID> uuidSupplier) throws IOException {
        super(serverAddress, port);
        this.uuid = uuidSupplier.get();
    }
}

并在子类中将其用作

class SomeConnection extends IdentifiedConnection {

    public SomeConnection(String serverAddress, int port) throws IOException {
        super(serverAddress, port, SomeConnection::createUUID);
    }

    public static UUID createUUID() {
        return ...;
    }

}

关于java - 在构造函数中调用可重写的方法是不好的。有异常(exception)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27217050/

相关文章:

java - 我的 peek() 方法不会返回队列的头部

java - Hadoop序列化和反序列化

java - 在 super 构造函数运行之前初始化字段?

c# - 隐式 (bool) 和 == 运算符覆盖 - 正确处理 if 语句

java - 多次调用 PrintWritter print() 或添加字符串然后只打印一次有什么区别?哪个更好?

java - 无法在 Android 上使用 HttpURLConnection 将数据发布到站点

c++ - 为什么第二个变量在现场没有变化?

c++ - 当没有显式关键字与单参数构造函数一起使用时,编译器可以发出警告吗?

java - Java 中的函数覆盖重载

c++ - 需要覆盖逆变变通方法