2009-10-15 8 views
54

Come ormai molte persone sono dolorosamente consapevoli, l'API Java per la gestione delle date del calendario (in particolare le classi java.util.Date e java.util.Calendar) è un pasticcio terribile.Perché l'API della data Java (java.util.Date, .Calendar) è un problema?

Fuori della parte superiore della mia testa:

  • Data è mutevole
  • Data rappresenta un timestamp, non una data
  • un modo semplice per la conversione tra i componenti data (giorno, mese, anno .. .) e data
  • Calendar è goffo da usare, e cerca di combinare diversi sistemi di calendario in una sola classe

This post lo riassume abbastanza bene e anche lo JSR-310 espande questi problemi.

Ora la mia domanda è:

Come ha fatto queste classi riuscire ad entrare nella Java SDK? La maggior parte di questi problemi sembra abbastanza ovvia (in particolare Data è mutevole) e avrebbe dovuto essere facile da evitare. Quindi come è successo? Pressione del tempo? O i problemi sono evidenti solo a posteriori?

Mi rendo conto che questa non è una domanda di programmazione, ma troverei interessante capire come il design dell'API potrebbe andare così male. Dopotutto, gli errori sono sempre una buona opportunità di apprendimento (e sono curioso).

+1

Una doppia negazione è sempre di cattivo gusto ... Date è mutabile, non data non è immutabile. –

+2

Speriamo che le nuove API Date e Time di JSR-310, basate su Joda-Time, verranno fornite in Java 7. –

+4

E DateFormat non è progettato per essere thread-safe ... (http://bugs.sun.com /bugdatabase/view_bug.do?bug_id=4093418) – Arjan

risposta

40

Qualcuno ha messo meglio di quanto potessi mai dire:

  • Classe Date rappresenta un istante specifico nel tempo, con millisecondo precisione. Il design di questa classe è uno scherzo molto brutto, un discreto esempio di di come anche i bravi programmatori sbagliano. La maggior parte dei metodi nella data sono deprecati, sostituiti dai metodi nelle classi seguenti.
  • Classe Calendar è una classe astratta per la conversione tra un oggetto Date e una serie di campi di numeri interi, come l'anno, il mese, il giorno e l'ora.

  • Classe GregorianCalendar è l'unica sottoclasse di Calendar nel JDK. Effettua le conversioni Date-to-fields per il sistema di calendario in uso comune .Sun ha concesso in licenza questa spazzatura ipersensibile di Taligent - un esempio sobrio di come i programmatori medi falliscono.

da programmatori Java FAQ, versione dal 07.X.1998, da Peter van der Linden - questa parte è stato rimosso da versioni successive però.

Per quanto riguarda la mutabilità, molte delle prime classi JDK ne risentono (Point, Rectangle, Dimension, ...). Ottimizzazioni errate, ne ho sentito dire qualcuno.

L'idea è che si desidera poter riutilizzare gli oggetti (o.getPosition().x += 5) anziché creare copie (o.setPosition(o.getPosition().add(5, 0))) come si ha a che fare con immutables. Potrebbe anche essere stata una buona idea con le prime VM, mentre molto probabilmente non è con le VM moderne.

+1

Le classi geometriche sono mutabili e alcune hanno campi pubblici perché molti swing sono creati da Swing e all'inizio è stato un trucco per migliorare le prestazioni. –

+3

Mi piace la citazione. – Davie

+1

@mP, ho aggiornato il mio post per includerlo. – gustafc

20

Le prime API di Java non sono altro che un prodotto del loro tempo. L'immutabilità divenne solo un concetto popolare anni dopo. Tu dici che l'immutabilità è "ovvia". Potrebbe essere vero ora ma non lo era allora. Proprio come l'iniezione di dipendenza è ora "ovvia" ma non è stata 10 anni fa.

È stato anche un tempo costoso creare oggetti Calendar.

Rimangono tali per ragioni di compatibilità all'indietro. Ciò che è forse più sfortunato è stato il fatto che una volta che l'errore è stato realizzato la vecchia classe non è stata deprecata e sono state create nuove classi data/ora per tutte le API in futuro. Questo si è in qualche misura verificato con l'adozione di JDK 8 di un'API JodaTime like (java.time, JSR 310) ma in realtà è troppo poco tardi.

+1

Data precedente al calendario di diverse versioni. La data era lì dall'inizio e non può essere rimossa facilmente. Il calendario è stato aggiunto perché la data è incompleta. –

8

Il tempo non è di per sé facile da misurare e da gestire. Basta guardare la lunghezza dell'articolo di Wikipedia su time. E poi, ci sono diverse comprensioni sul tempo stesso: un punto temporale absoulte (come costante), un punto temporale in un determinato luogo, un intervallo di tempo, la risoluzione del tempo ....

Mi ricordo quando ho visto java.util.Date la prima volta (JDK 1.0?) ero davvero felice a riguardo. Le lingue che conoscevo non avevano questa caratteristica. Non avevo pensato alla conversione del tempo, ecc.

Penso che sia un casino, perché tutto ciò che cambia lascia un casino se ci si evolve da un livello di comprensione (XMLGregorianCaldender vs. Date) e requisiti (Nanoseconds, passato 2030) a livello più alto, ma mantenendo il vecchio intatto. E java.util.Date non è un'eccezione. Basta guardare il sottosistema I/O o la transizione da AWT a Swing ...

E per questo motivo "a volte dovremmo premere il pulsante di ripristino". (chi l'ha detto, btw?)