有没有可能扩展标记为最终的Joda-Time类?

2022-05-29 00:00:00 java jodatime

我真的很喜欢Joda-Time,但我遇到了一些我认为有问题的事情。我想扩展一些类,特别是DateTime、LocalDate和LocalDateTime。但它们被标记为"最终版本"。

我发现了一个非常古老的线程,它被解释为确保类保持不变的一种方式。http://osdir.com/ml/java-joda-time-user/2006-06/msg00001.html

我还在这里找到了一个线索,因此,是否需要将Java类标记为最终类以确保不变性是有争议的。Why would one declare an immutable class final in Java?

无论如何,我发现不能扩展这些类是一个很大的限制。除了下载和修改源文件之外,还有什么可以做的来创建这些类的扩展版本吗?

编辑-讨论:

扩展类的能力是面向对象编程中最强大和最有用的概念之一。这可以始终有用。类的作者不可能100%确定他/她的超级Duper类在扩展到涵盖无人能预见的用例时对某些程序员不会更有用。

Joda-Time类被标记为"最终"的明显原因是为了确保不可能有人创建一个可变的扩展类,并将其用于依赖于Joda-Time对象不可变的现有程序。因此,在某种程度上,将这些类标记为"最终"是因为缺少一种允许将类标记为"不可变"的Java语言机制,因此它们可以被扩展,但前提是扩展的类也被标记为"不可变"。

因此,鉴于Java中缺少"不可变"关键字,我可以理解Joda-Time的作者希望避免这种情况。

以下解决方案可行吗?例如,我们可以有一个结构,其中LocalDate派生自LocalDateNonFinal吗?LocalDate是一个标记为"Final"的空类。所有功能都在LocalDateNonFinal中。

因此,如果您确实想要扩展LocalDate类,并且只打算在您自己的程序中使用扩展类,那么您可以扩展LocalDateNonFinal,并将其命名为MyLocalDate。这不会将其他模块暴露给您可能的错误,因为它们仍将需要LocalDate,并且不接受LocalDateNonFinal或您的MyLocalDate。

这可以与试图教育想要扩展这些类的程序员相结合,警告他们如果意外地创建了一个可变版本并仍然将其视为不可变的版本,则可能会出现问题。并指出这些扩展类将不能与期望常规("最终")类的其他模块一起使用。

PS。我会在几天后发布我的变通解决方案,当我完全确定的时候。到目前为止,我已经对其中两个答案投了赞成票--谢谢你的评论和建议。我目前倾向于按照德米特里·扎伊采夫(Dmitry Zaitsev)的建议采用包装式解决方案。


解决方案

您可以将最终类包装到您自己的类中,提供您想要的任何操作,并提供将返回原始Joda-Time对象的"view"方法。就像这样:

public class MyJodaExtension {

    private final DateTime dateTime;

    public MyJodaExtension(DateTime dateTime) {
        this.dateTime = dateTime;
    }

    public boolean myOperation() {
        return false;  // or whatever you need
    }

    public DateTime asDateTime() {
        return dateTime;
    }

}

使用这种方法,您甚至可以使MyJodaExtension变,并根据需要提供DateTime的不同实例(但我希望您不要这样做,不变的类很棒)。

正如Nathan Hughes所说,您不可能将这种"继承的"类传递给其他库或任何需要原始Joda Time类的代码。

相关文章