我非常喜欢Joda-Time,但遇到了一些我认为是问题的事情。我想扩展一些类,特别是DateTime,LocalDate和LocalDateTime。但是它们被标记为“最终”。
我发现了一个非常旧的线程,将其解释为确保类保持不变的一种方式。 http://osdir.com/ml/java-joda-time-user/2006-06/msg00001.html
我还在SO上找到了一个线程,在该线程中需要讨论将Java类标记为final以确保不变性的问题。 Why would one declare an immutable class final in Java?
无论如何,我发现这是我无法扩展这些类的主要限制。除了下载源文件并对其进行修改之外,还有什么能做的来创建这些类的扩展版本?
编辑-讨论:
扩展类的能力是面向对象编程中最强大,最有用的概念之一。这总是有用的。类的作者不可能100%地确定当扩展到涵盖没人能预见的用例时,他/她的超级二重奏类对某些程序员将不再有用。
Joda-Time类标记为“ final”的明显原因是为了确保某人无法创建可变的扩展类,并将其与依赖于Joda-Time对象不可变的现有程序一起使用。因此,在某种程度上,将这些类标记为“最终”是由于缺少Java语言机制,该机制允许将类标记为“不可变”,因此可以对其进行扩展,但前提是必须将扩展类也标记为“不可变” ”。
因此,鉴于Java中缺少“不变”关键字,我可以理解,Joda-Time的作者希望避免这种情况。
以下解决方案是否可行?我们是否可以有一个结构,例如LocalDate是从LocalDateNonFinal派生的? LocalDate是一个标记为“最终”的空类。所有功能都在LocalDateNonFinal中。
因此,如果您确实想扩展LocalDate类,并且只打算在自己的程序中使用扩展类,则可以扩展LocalDateNonFinal,并将其命名为MyLocalDate。这不会使其他模块面临您可能的错误,因为它们仍然需要LocalDate,并且不会接受LocalDateNonFinal或MyLocalDate。
这可以与尝试教育想要扩展这些类的程序员结合在一起,如果他们偶然创建了一个可变版本并仍然将其视为不可变的,则警告他们可能出现的问题。并指出,这些扩展类将无法与期望常规(“最终”)类的其他模块一起使用。
PS。完全确定后,我会在两天内发布解决方法。到目前为止,我已经投票给了两个答案-感谢您的评论和建议。我目前正在按照Dmitry Zaitsev建议的方式寻求类似包装器的解决方案。
最佳答案
您可以将最终类包装到自己的类中,提供所需的任何操作,并提供“ view”方法,该方法将返回原始的Joda-time对象。像那样:
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时间类的代码。