Pergunta

Houve incompatibilidade entre releases Java, onde o código-fonte Java / arquivos de classe Java visando Java versão X não irá compilar / executar sob a versão Y (onde Y> X)?

Por "versão Java" I versões médios, tais como:

  • JDK 1.0 (janeiro de 1996)
  • JDK 1.1 (fevereiro de 1997)
  • J2SE 1.2 (Dezembro de 1998)
  • J2SE 1.3 (maio de 2000)
  • J2SE 1.4 (fevereiro de 2002)
  • J2SE 5.0 (setembro de 2004)
  • Java SE 6 (dezembro de 2006)

Regras da casa:

  • Por favor, inclua referências e exemplos de código, quando possível.
  • Tente ser / concreto muito específico em sua resposta.
  • Uma classe que está sendo marcado como @deprecated não conta como uma incompatibilidade de trás.
Foi útil?

Solução

notas de compatibilidade para várias versões:

O primeiro grande soluço que me lembro foi a introdução de assert em Java 1.4. Isso afetou um monte de código JUnit .

Outras dicas

Em primeiro lugar, a Sun realmente considera todos os lançamentos que você mencionou (excepto 1.0 é claro) para ser menor lançamentos, não mais importantes.

Não tenho conhecimento de quaisquer exemplos de incompatibilidade binária nesse tempo. No entanto, tem havido alguns exemplos de incompatibilidade fonte:

  • Em Java 5, "enum" se tornou uma palavra reservada; que não era antes. Portanto, havia arquivos de origem que enum usado como um identificador que compilar em java 1.4 que não compilar em java 5.0. No entanto, você pode compilar com -source 1.4 de contornar este problema.

  • Adicionando métodos a uma interface pode quebrar compatibilidade de origem também. Se você implementar uma interface, e depois tentar compilar que a implementação com um JDK que adiciona novos métodos para a interface, o arquivo de origem deixarão de compilação com êxito, porque não implementar todos os membros da interface. Este tem freqüentemente aconteceu com java.sql.Statement e as outras interfaces JDBC. As formas compiladas dessas implementações "inválidos" irá ainda trabalho a menos que você realmente chamar um dos métodos que não existe; se você fizer isso, um MissingMethodException será lançada.

Estes são alguns exemplos que me lembro fora do topo da minha cabeça, pode haver outros.

O java.sql.Connection interface foi estendido de Java 1.5 para Java 1.6 tomada de compilação de todas as classes que implementaram esta interface falhar.

Cada lançamento do balanço quebrou alguma coisa por nós, de 1,3 a 1.6.

A questão JDBC já foi mencionado, mas o código existente funcionou.

De 1,5 a 1,6, houve uma mudança no comportamento de soquete que quebrou o cliente Cisco.

É claro que novas palavras-chave reservadas foram introduzidas.

O grande que eu acho que foi verdadeiramente imperdoável da parte de Sun foi System.getenv (). Ele trabalhou em 1,0, e depois foi substituído e mudado para lançar um erro em todas as plataformas sob a justificativa bastante duvidosa de que o Mac não tem variáveis ??de ambiente do sistema. Em seguida, o Mac tem variáveis ??de ambiente do sistema, portanto, em 1,5 foi undeprecated e obras. Não há justificativa razoável para fazer isso. Retornar um conjunto vazio em um Mac (Swing tem problemas de multi-plataforma muito maiores se você quiser se preocupam com esse nível de consistência de plataforma cruzada) ou mesmo em todas as plataformas.

Nunca concordei com eles desligar o recurso, mas para mudá-lo para lançar um erro foi apenas uma alteração de quebra pura que se eles iriam fazer, eles deveriam ter acabado de remover o método inteiramente.

Mas, realmente 1,0-1,1 eles estavam menos preocupados com a compatibilidade com versões anteriores. Por exemplo, eles caíram "protegida privada" como um modificador.

Assim, o resultado é que cada versão muda o suficiente para exigir a avaliação perto, por isso você ainda vê muitas 1,4 perguntas aqui no SO.

A principal delas que eu posso pensar é a introdução de novas palavras reservadas:

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

Qualquer código que anteriormente utilizado esses valores como identificadores não compilar sob uma versão posterior.

Uma outra questão que eu me lembro que causam problemas em um projeto que eu trabalhei foi que não havia uma mudança na visibilidade padrão de JInternalFrames entre 1,2 e 1,3 . Eles eram visíveis por padrão, mas quando nós atualizado para 1.3 todos eles pareciam ter desaparecido.

entre 1,3 e 1,4 a interpretação de Long.parseLong (String) tratadas a cadeia vazia de forma diferente. 1.3 retorna um valor 0, enquanto que 1.4 lança uma NumberFormatException.

Não são necessários recompila, mas o código de trabalho parou de funcionar se baseou no comportamento 1.3.

A semântica da modelo de memória < a href = "http://jcp.org/en/jsr/detail?id=133" rel = "nofollow noreferrer"> mudou 1,4-1,5 . Foi alterado para permitir que para além de outras coisas dobro verificado bloqueio novamente. (Acho semântica voláteis foram corrigidos.) Ele foi quebrado.

A seguir irá compilar em Java 1.4, mas não Java 1.5 ou posterior.

(Java 5 introduziu 'enum' como palavra-chave Nota:.. Ele irá compilar em Java 5, se o "-source 1.4" opção é fornecida)

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

Obviamente, a convenção de nomenclatura de nomes libertação é não compatível com versões anteriores .

  • JDK 1.0 (23 de janeiro, 1996)
  • JDK 1.1 (19 de fevereiro, 1997)
  • J2SE 1.2 (08 de dezembro de 1998)
  • J2SE 1.3 (08 de maio de 2000)
  • J2SE 1.4 (06 de fevereiro de 2002)
  • J2SE 5.0 (30 setembro de 2004)
  • Java SE 6 (11 dezembro de 2006)
  • Java SE 6 Update 10, Atualização 12, Atualização 14, Atualização 16
  • Java SE 7 ??? JDK7?

( A lista é da Wikipedia .)

No entanto, outro exemplo de compatibilidade quebra java.sql:

Em 1,5 um método (Data) compareTo foi adicionado em java.sql.Timestamp. Este método seria jogar uma ClassCastException se a data fornecida não era uma instância de java.sql.Timestamp. Claro, java.sql.Timestamp estende data e data já tinha um método compareTo (Date), que trabalhou com todas as datas, então isso significa que o código que comparou um Timestamp a um (não-Timestamp) Data iria quebrar em tempo de execução em 1,5 .

É interessante notar que parece que 1,6 parece ter corrigido este problema. Enquanto a documentação para java.sql.Timestamp.compareTo (Data) ainda diz "Se o argumento não é um objeto Timestamp, este método lança um objeto ClassCastException", a implementação real diz o contrário. Meu palpite é que este é um erro documentação.

See report on API changes for the JRE class library here: http://abi-laboratory.pro/java/tracker/timeline/jre/

The report includes backward binary- and source-compatibility analysis of Java classes.

The report is generated by the japi-compliance-checker tool.

enter image description here

...

enter image description here

Another interesting analysis for JDK 1.0-1.6 you can find at Japitools JDK-Results page.

As Sean Reilly said, a new method can break your code. Besides the simple case that you have to implement a new method (this will produce a compiler warning) there is a worst case: a new method in the interface has the same signature as a method you do already have in your class. The only hint from the compiler is a warning that the @Override annotation is missing (Java 5 for classes, the annotation is supported for interfaces in Java 6 but optional).

I have not tried it but in theory this would work in Java 1.1 and break in Java 1.2. (More info here)

public class Test {
    float strictfp = 3.1415f;
}

From personal experience, we had some AWT/Swing text fields embedded in a SWT_AWT frame in 1.5, that ceased to be editable after upgrading to 1.6.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top