65

ほとんどの人が痛感しているように、カレンダーの日付を処理するための Java API (具体的にはjava.util.Dateとのクラスjava.util.Calendar) はひどい混乱です。

私の頭の上から:

  • 日付は変更可能です
  • 日付は日付ではなくタイムスタンプを表します
  • 日付コンポーネント (日、月、年など) と日付を簡単に変換する方法がない
  • Calendar は扱いにくく、異なる暦体系を 1 つのクラスにまとめようとします

この投稿はそれを非常にうまくまとめており、JSR-310はこれらの問題についても説明しています。

今私の質問は:

これらのクラスはどのようにして Java SDK に組み込まれたのでしょうか? これらの問題のほとんどはかなり明らかで (特に Date は変更可能です)、回避するのは簡単なはずです。それで、それはどのように起こったのですか?時間的制約?それとも、問題は振り返ってみれば明らかですか?

これは厳密にはプログラミングの問題ではないことは理解していますが、API 設計がどのようにうまくいかないかを理解するのは興味深いことです。結局のところ、間違いは常に良い学習の機会です (私は興味があります)。

4

4 に答える 4

45

誰かが私がこれまでに言うことができなかったよりもうまく言いました:

  • クラスDateは、ミリ秒の精度で特定の瞬間を表します。このクラスの設計は非常に悪い冗談です。優れたプログラマーでさえ失敗するという冷静な例です。Date のほとんどのメソッドは廃止され、以下のクラスのメソッドに置き換えられました。
  • クラスは、 オブジェクトと、年、月、日、時間などの一連の整数フィールドとのCalendar間で変換を行うための抽象クラスです。Date

  • Classは、JDKGregorianCalendarの唯一のサブクラスです。Calendar一般的に使用されている暦体系の日付からフィールドへの変換を行います。Sun は、Taligent からこの過度に設計されたがらくたのライセンスを取得しました。

Java Programmers FAQ 、07.X.1998 以降のバージョン、Peter van der Lindenから- ただし、この部分は後のバージョンから削除されました。

可変性に関しては、初期の JDK クラスの多くがそれに悩まされています ( PointRectangleDimension、 ...)。最適化の方向を誤った、と言う人もいます。

不変オブジェクトの場合のようにo.getPosition().x += 5コピーを作成する ( ) のではなく、オブジェクトを再利用できるようにしたい ( ) という考え方です。o.setPosition(o.getPosition().add(5, 0))これは初期の VM では良いアイデアだったかもしれませんが、最新の VM ではそうではない可能性が高いです。

于 2009-10-15T09:45:43.037 に答える
21

Java の初期の API は、その時代の産物にすぎません。不変性が一般的な概念になったのは、それから数年後のことです。不変性は「明白」だとおっしゃいます。今はそうかもしれませんが、当時はそうではありませんでした。依存性注入が今や「明白」になったように、10 年前はそうではありませんでした。

また、Calendar オブジェクトを作成するのは、かつてコストがかかりました。

下位互換性の理由から、そのままです。おそらくもっと残念なことは、間違いが認識された後、古いクラスが非推奨にならず、今後すべての API に対して新しい日付/時刻クラスが作成されたことです。これは、JDK 8 が JodaTime のような API ( 、JSR 310) を採用したことである程度発生しましたjava.timeが、実際には遅すぎます。

于 2009-10-15T09:41:16.263 に答える
9

時間自体を測定し、処理することは容易ではありません。timeに関するウィキペディアの記事の長さを見てください。そして、時間自体についてはさまざまな理解があります。絶対的な時点 (定数として)、特定の場所での時点、時間範囲、時間の解像度などです。

初めて java.util.Date を見たとき (JDK 1.0?) は本当に嬉しかったです。私が知っている言語には、そのような機能はありませんでした。時間換算などは考えていませんでした。

なぜなら、あるレベルの理解 (XMLGregorianCaldender 対 Date) と要件 (ナノ秒、過去 2030 年) からより高いレベルに進化し、古いものはそのままにしておくと、変化するすべてが混乱したままになるからです。そして java.util.Date は例外ではありません。I/O サブシステムまたは AWT から Swing への移行を見てください...

そのため、「リセット ボタンを押す必要がある場合もあります」。(ところで、誰が言ったの?)

于 2009-10-15T11:38:13.737 に答える
5

次の投稿が興味深いかもしれません。まず、Calendar クラスがどのようにして Java API に取り込まれたかを説明し、日付クラスの起源に光を当てます。

非常に機能不全に陥ったデザインの7つの習慣

于 2011-07-14T17:47:20.020 に答える