Domanda

Si sono verificate incompatibilità tra le versioni Java in cui il codice sorgente Java/i file di classe Java destinati alla versione Java X non vengono compilati/eseguiti nella versione Y (dove Y > X)?

Per "versione Java" intendo versioni come:

  • JDK 1.0 (gennaio 1996)
  • JDK 1.1 (febbraio 1997)
  • J2SE 1.2 (dicembre 1998)
  • J2SE 1.3 (maggio 2000)
  • J2SE 1.4 (febbraio 2002)
  • J2SE 5.0 (settembre 2004)
  • Java SE 6 (dicembre 2006)

Regole di casa:

  • Si prega di includere riferimenti ed esempi di codice ove possibile.
  • Cerca di essere molto specifico/concreto nella tua risposta.
  • Una classe contrassegnata come @Deprecated non conta come incompatibilità con le versioni precedenti.
È stato utile?

Soluzione

Note di compatibilità per le diverse versioni:

Il primo grande incidente di percorso che ricordo è stata l'introduzione di assert in Java 1.4. Ha colpito un sacco di codice JUnit .

Altri suggerimenti

Prima di tutto, Sun in realtà considera tutti i rilasci hai citato (diverso da 1.0 ovviamente) per essere stampa, non quelli principali minori.

Sono a conoscenza di esempi di incompatibilità binaria in quel momento. Tuttavia, ci sono stati alcuni esempi di incompatibilità fonte:

  • In Java 5, "enum" è diventata una parola riservata; non era prima. Pertanto, non vi erano file di origine che hanno usato enum come un identificatore che avrebbe compilato in Java 1.4 che non sarebbe la compilazione in Java 5.0. Tuttavia, si potrebbe compilare con -source 1.4 per aggirare questo.

  • Aggiunta di metodi ad un'interfaccia possono rompere compatibilità sorgente pure. Se si implementa l'interfaccia, e poi tenta di compilare che l'attuazione di un JDK che aggiunge nuovi metodi per l'interfaccia, il file di origine non sarà più compilare correttamente, perché non implementa tutti i membri della interfaccia. Questo è spesso accaduto con java.sql.Statement e le altre interfacce JDBC. Le forme compilate di queste implementazioni "non valido" continueranno a funzionare a meno che non si chiama in realtà uno dei metodi che non esiste; se si fa questo, un MissingMethodException sarà gettato.

Questi sono alcuni esempi che posso ricordare al largo della parte superiore della mia testa, ci possono essere altri.

Il java.sql.Connection interfaccia è stata estesa da Java 1.5 per Java 1.6 facendo compilazione di tutte le classi che hanno realizzato questa interfaccia fallire.

Ogni release di Swing è rotto qualcosa per noi, da 1.3 a 1.6.

Il problema JDBC è già stato menzionato, ma il codice esistente lavorato.

Da 1,5-1,6 c'è stato un cambiamento nel comportamento di Socket che ha rotto il client Cisco.

Naturalmente sono state introdotte nuove parole chiave riservate.

Il grande e credo che era veramente imperdonabile da parte di Sun era System.getenv (). Ha funzionato a 1.0, e poi è stata sconsigliata e ha cambiato per gettare un errore su tutte le piattaforme sotto l'piuttosto dubbia giustificazione che il Mac non ha avuto le variabili di ambiente di sistema. Poi il Mac ha variabili d'ambiente di sistema, quindi nella 1.5 è stato undeprecated e lavora. Non v'è alcuna giustificazione ragionevole per farlo. Restituisce un insieme vuoto su un Mac (Swing ha molto più grandi problemi di cross-platform, se si desidera prendersi cura di quel livello di croce consistenza piattaforma) o anche su tutte le piattaforme.

Non ho mai d'accordo con loro di spegnere la funzione, ma di cambiarlo per gettare un errore è stato solo un cambiamento puro di rottura che, se avevano intenzione di fare, avrebbero dovuto appena rimosso il metodo del tutto.

Ma, in realtà 1,0-1,1 erano meno preoccupati per compatibilità all'indietro. Ad esempio, hanno abbandonato "privata protetta" come modificatore.

Quindi, il risultato è che ogni versione cambia abbastanza da richiedere un'attenta valutazione, è per questo che si vede ancora molti 1.4 domande qui su SO.

Il principale che mi viene in mente è l'introduzione di nuove parole riservate:

Java 1.3: strictfp
Java 1.4: assert
Java 5.0: enum

Qualsiasi codice che in precedenza utilizzato questi valori come identificatori non avrebbe compilato in una versione successiva.

Un altro problema che mi ricordo che causano problemi su un progetto che ho lavorato era che c'era un cambiamento della visibilità predefinita dei JInternalFrames tra 1.2 e 1.3 . Erano visibile di default, ma quando abbiamo aggiornato alla 1.3 tutti sembravano essere scomparsi.

Tra 1.3 e 1.4 l'interpretazione di Long.parseLong(String) gestiva la stringa vuota in modo diverso.1.3 resi a 0 valore, mentre 1,4 lancia a NumberFormatException.

Non sono necessarie ricompilazioni, ma il codice funzionante smetteva di funzionare se si basava sul comportamento 1.3.

La semantica della < a href = "http://jcp.org/en/jsr/detail?id=133" rel = "nofollow noreferrer"> cambiato 1,4-1,5 . E 'stato cambiato per consentire oltre ad altre cose doppia controllato bloccaggio di nuovo. (Credo che la semantica volatili sono state fissate.) E 'stato rotto.

Di seguito verrà compilato in Java 1.4, ma non Java 1.5 o successivo.

(Java 5 ha introdotto 'enum' come parola chiave. Nota: si compilerà in Java 5 se l'opzione "-source 1.4" è fornito.)

public class Example {
    public static void main(String[] args) {
        String enum = "hello";
    }
}

Ovviamente la convenzione di denominazione di rilasciare nomi è non è compatibile con le versioni precedenti .

  • JDK 1.0 (23 gennaio 1996)
  • JDK 1.1 (19 febbraio 1997)
  • J2SE 1.2 (8 dicembre 1998)
  • J2SE 1.3 (8 maggio 2000)
  • J2SE 1.4 (6 febbraio 2002)
  • J2SE 5.0 (30 Settembre 2004)
  • Java SE 6 (11 dicembre 2006)
  • Java SE 6 Update 10, Update 12, Update 14, Aggiornamento 16
  • Java SE 7 ??? JDK7?

( L'elenco è da Wikipedia .)

Ancora un altro esempio di java.sql compatibilità rottura:

In 1.5 un metodo compareTo (Data) è stato aggiunto al java.sql.Timestamp. Questo metodo potrebbe gettare un ClassCastException se la data in dotazione non è stato un caso di java.sql.Timestamp. Naturalmente, java.sql.Timestamp estende Data e Data già avuto un metodo compareTo (Data), che ha lavorato con tutte le date, quindi questo significa che il codice che ha confrontato un timestamp a un (non timestamp) Data si rompono in fase di esecuzione in 1.5 .

E 'interessante notare che sembra che 1.6 sembra aver risolto questo problema. Mentre la documentazione per java.sql.Timestamp.compareTo (data), dice ancora "Se l'argomento non è un oggetto Timestamp, questo metodo genera un oggetto ClassCastException", l'attuazione effettiva dice il contrario. La mia ipotesi è che si tratta di un bug di documentazione.

Si veda la relazione sui cambiamenti API per la libreria di classi JRE qui: http: // abi-laboratory.pro/java/tracker/timeline/jre/

Il rapporto include all'indietro analisi binary- e la fonte-compatibilità di classi Java.

Il rapporto è generato dal JAPI-compliance-checker strumento.

entrare descrizione dell'immagine qui

...

entrare descrizione dell'immagine qui

Un altro interessante analisi per JDK 1,0-1,6 potete trovare a Japitools JDK -I risultati pagina.

Come ha detto Sean Reilly, un nuovo metodo può rompere il vostro codice. Oltre al caso semplice che è necessario implementare un nuovo metodo (questo produrrà un avviso del compilatore) non v'è un caso peggiore: un nuovo metodo nell'interfaccia ha il stessa firma come metodo si dispone già nella classe. L'unico indizio dal compilatore è un avvertimento che l'annotazione @Override manca (Java 5 per le classi, l'annotazione è supportata per le interfacce in Java 6 ma facoltativo).

Non ho provato, ma in teoria questo dovrebbe funzionare in Java 1.1 e rompere in Java 1.2. (Più informazioni qui )

public class Test {
    float strictfp = 3.1415f;
}

Per esperienza personale, abbiamo avuto alcuni campi di testo AWT / Swing incorporati in un telaio SWT_AWT in 1.5, che ha cessato di essere modificabile dopo l'aggiornamento a 1.6.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top