2009-10-15 4 views
54

ほとんどの人が気づいているように、カレンダーの日付(特にクラスjava.util.Datejava.util.Calendar)を処理するためのJava APIはひどい混乱です。私の頭の上オフJava date API(java.util.Date、.Calendar)がこのような混乱を引き起こすのはなぜですか?

  • 日は変更可能
  • 日は、タイムスタンプ、ない日
  • 日付コンポーネント(日、月、年の間で変換する簡単な方法を表し..です。)と日付
  • カレンダーが使用する不格好で、1クラス

に別のカレンダーシステムを統合しようとしますはこれを非常にうまくまとめており、JSR-310もこれらの問題を解消しています。

今私の質問は:

これらのクラスは、Java SDKにそれを作ったどのように?これらの問題のほとんどはかなり明白であり(特にDateは変更可能です)、避けがたいはずです。ではどうしたの?時間的制約?または、問題は振り返って明らかですか?

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

+1

二重否定は常に悪い形です...日付が変更できません日付は不変ではないです。 –

+2

Joda-Timeに基づくJSR-310の新しい日付と時刻APIは、Java 7で出荷されることを願っています。 –

+4

DateFormatはスレッドセーフに設計されていません...(http://bugs.sun.com /bugdatabase/view_bug.do?bug_id=4093418) – Arjan

答えて

40

誰かが私が今までそれを言うことができるよりも、より良いそれを置く:

  • クラスDateミリ秒 精度で、特定の時点を表します。このクラスのデザインは、非常に悪い冗談です。良いプログラマでさえどうしたらいいのかという、まったくわかりにくい例の です。 Dateのメソッドのほとんどは非難され、以下のクラスのメソッドに置き換えられました。
  • クラスCalendarDate オブジェクトと、年、月、日、時間などの整数フィールドセット間の変換を行うための抽象クラスです。

  • クラスGregorianCalendarは、JDKのCalendarの唯一のサブクラスです。 カレンダーシステムの日付からフィールドへの変換は、 でよく使用されます。サンはTaligentからのこの重大な迷惑をライセンス供与した。 平均的なプログラマーたちがどうやって乱れているかの冷静な例。 のJavaプログラマよくある質問から

、07.X.1998からのバージョンでは、ピーター・ファン・デル・リンデンによって - この部分は、しかしそれ以降のバージョンから削除されました。

可変性に関しては、初期のJDKクラスには多くの人が苦しんでいます(PointRectangleDimension、...)。間違った最適化、私はいくつか言うと聞いた。

immutablesと同じように、コピー(o.setPosition(o.getPosition().add(5, 0)))を作成するのではなく、オブジェクト(o.getPosition().x += 5)を再利用できるようにするという考えがあります。これは初期のVMでは良い考えであったかもしれませんが、現代のVMではそうではない可能性が高いです。

+1

ジオメトリクラスは変更可能であり、Swingによってたくさんのインセンが作成され、最初はパフォーマンスを向上させるためのハックだったため、パブリックフィールドを持つものもあります。 –

+3

私は引用が好きです。 – Davie

+1

@mP、これを含めるために私のポストを更新しました。 – gustafc

20

Javaの初期のAPIは、時間の産物に過ぎません。不変性はその後、普及したコンセプトになりました。あなたは、不変性が「明白」であると言います。それは当然のことかもしれませんが、そうではありませんでした。依存関係注入は今や「明らか」ですが、10年前ではありませんでした。

カレンダーオブジェクトを作成することも同時に高価でした。

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

+1

日付は複数のリリースでカレンダーに先行します。日付は最初からあり、簡単に削除することはできません。日付が不完全なため、カレンダーが追加されました。 –

8

時間自体は測定して扱いにくいです。ちょうど約timeのウィキペディアの記事の長さを見てください。そして、時間そのものについての異なる理解があります:アブソリュートタイムポイント(定数として)、特定の場所のタイムポイント、時間レンジ、時間の分解....

私は覚えています。初めてjava.util.Dateを見た(JDK 1.0?)私はで、実際にはでした。私が知っていた言語にはそのような特徴はなかった。

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

そして、そのために、「リセットボタンを押してください。」 (誰がそれを言ったのでしょうか?)

5

興味深い記事があります。 Calendarクラスが最初にJava APIにどのように入ってきたのか、そして日付クラスの起源についてのいくつかのことを明らかにしています。

The Seven Habits of Highly Dysfunctional Design

関連する問題