为什么 java.sql.Timestamp 扩展 java.util.Date

Why does java.sql.Timestamp extend java.util.Date

当我看到这个的时候,我感到很困惑:

  public class Timestamp extends java.util.Date {
    //...
    public boolean equals(java.lang.Object ts) {
      if (ts instanceof Timestamp) {
        return this.equals((Timestamp)ts);
      } else {
        return false;
      }
    }
    public int hashCode() {
        return super.hashCode();
    }

确实用粗体记录了<strong>注意</strong> (参见 https://docs.oracle.com/javase/7/docs/api/java/sql/Timestamp.html

做出这样一个对我来说非常糟糕的决定的原因可能是什么? 为什么不在与 java.util.Date 对象进行比较时调用 super.equals(this) 来使相等比较对称?

What could be the cause to make such a, to me very bad, decision? Why not call super.equals(this) when compared to a java.util.Date object to make the equal comparison symmetrical?

原因可能只有作者知道,没有记录。但是 super.equals(this) 也不会尊重平等契约。由于 Date 错过了纳秒精度,因此唯一的方法就是将纳秒排除在外。但这会导致两个不相等的 Timestamp 实例(具有不同的 nano 值)都等于同一个 Date 实例的情况,这意味着实现是不可传递的。

Date.equals需要Dates,所以super.equals不可行。 Timestamp.equalsequals(Timestamp ts) 超载,因此也遵守平等契约,需要 Timestamps。

重载有点过度设计;但我见过更糟糕的设计。

Timestamp 的 nanos 可能是新时间 API 的补充,旧 Date 中没有。

考虑到新时间 API 可能会在很远的将来取代这个 class,我认为没有理由提出任何更改请求。 (SQL 时间 classes 现在有点多余。)


Timestamp#equals(Object)
    checks for both to be a Timestamp (as by contract)
    calls Timestamp#equals(Timestamp)

Timestamp#equals(Timestamp)
    calls Date#equals
    and then also compares the extra nanos fields

"not feasible" 我的意思是没有比较两个对象的所有方面。

而是使用 java.time

正如其他人所说:

  • 这个 class 继承是糟糕的设计,有缺陷的 hack。
  • 现在没有实际意义,因为这个 class 现在是旧版,被 java.time.Instant 取代。

避免在 java.time 包之外找到所有旧的遗留日期时间 classes。

对于数据库,使用符合 JDBC 4.2 or later 的驱动程序直接与数据库交换 java.time 对象。你可以忘掉所有关于 java.sql.Timestamp 的事情。

存储:

Instant instant = Instant.now() ;
myPreparedStatement.setObject( … , instant ) ;

正在检索:

Instant instant = myResultSet.getObject( … , Instant.class ) ;

关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

从哪里获得java.time classes?

ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.