2013-09-04 3 views
14

私は似たような話題を見つけましたが、過度に複雑で、あまり同じではありません。それは事です。ここでは1.6で問題ない(最小)コードはありますが、1.7 javacではコンパイルできません。JDK 1.7では下位互換性が損なわれますか? (ジェネリック)

public class Test { 
    private static class A<T>{}; 
    private static class B{}; 
    private static class C{}; 

    B doSomething(A<B> arg){ 
     return new B(); 
    } 

    C doSomething(A<C> arg){ 
     return new C(); 
    } 
} 

1.7でエラーがこれです:

java: name clash: doSomething(Test.A<Test.C>) and doSomething(Test.A<Test.B>) have the same erasure 

私は型消去を理解し、なぜそれが間違っているコードです。 1.7で問題が発生したときに、1.6でコンパイルして実行しているプロジェクトでなぜこのコードを使用できるのか分かりません。なにが問題ですか?それは私たちがそうすることを可能にする1.6コンパイラのバグですか?書き換え以外の1.7で動作させることは可能ですか?

  • JDK1.6のjavacのバージョン:1.6.0_43
  • JDK1.7のjavacのバージョン:1.7.0_25

答えて

13

あなたは全く正しい、JLS3の下で、このコードはコンパイルされなかったんだと、これはでした1.6のバグ。

1.7のリリースでは、基盤となる型システムの多くが更新され、このバグが修正されました。その結果、いくつかの下位互換性の問題を犠牲にして型処理が改善されました。

1.7で動作させるために、私はリファクタリングがあなたの唯一の選択肢だと考えています。

+1

感謝を拒否されます。しかし、私はまだ彼らが後方互換性を破ったのが好きではありません。 – NeplatnyUdaj

+1

@NeplatnyUdaj:バグを修正しても下位互換性が失われません。 – newacct

+1

@newacct:多くのコードがそれに依存するかもしれないからだと思います。あなたはJLS全体を読む開発者を知っていますか? – NeplatnyUdaj

6

これはJava 7で修正されたjavacのバグの1つです。詳細はrelease notesにあります。私はあなたの唯一のオプションは、あなたがエリア

のJava 7に切り替えたい場合はそのコードを書き換えることで怖い:ツール
あらすじ:同じ消去された署名との2つのメソッドを定義することはできませんクラスが、戻り値の型が同じかどうかにかかわらず、クラスは同じ消去された署名を持つ2つのメソッドを定義することはできません。これはJLSのJava SE 7 Editionのセクション8.4.8.3に従います。 JDK 6コンパイラでは、署名は同じですが戻り値の型が異なるメソッドを使用できます。この動作は不正であるとJDK 7
で修正されています:

class A { 
    int m(List<String> ls) { return 0; } 
    long m(List<Integer> ls) { return 1; } 
} 

このコードは、JDK 5.0およびJDK 6の下でコンパイルし、JDK 7の下の説明のための

+0

「Java 5」と「Java 6」における「A」の動作はまったく何ですか?それは実際に適切なものを選んだのですか、それとも最初の(または最後の)ものを選んだだけですか? 'List 'でそれを呼び出そうとすればどうでしょうか? – Kevin

関連する問題