2011-11-18 18 views
5

ジェネリックで次の問題を発見しました。タイプバインドで使用されるジェネリック型からの型引数へのアクセス

public <T extends A<?>> void foo(T t) { 
    bar(t); 
} 

により、ワイルドカードには、getの戻り値の型の型情報は、()不足している:のは、次のメソッドの定義を想定してみましょう、今の汎用インタフェース

public interface A<X> { 
    X get(); 
    void doStuff(X x); 
} 

を考えてみましょう。したがって、私は新鮮な型変数にこのワイルドカードを「結合する」は、他のメソッドに委譲する必要があります。

FOOにあるバー()の呼び出しが許可されていない

private <X> void bar(A<X> t) { 
    X x = t.get(); 
    t.doStuff(x); 
} 
は、コンパイラは、次のエラーメッセージを出力します。

私は

にメソッドfoo()を変更した場合型式試験に

方法バー(A)は、

しかし引数(T)のために適用されません

です。どうして?これはコンパイラエラーですか?これに関するコメントは非常に高く評価されます。

注:

  • 私は単純に、ボイドのfoo(A)とメソッドfooを宣言していない理由は、私が実際に上位タイプバウンドinteresection(&)を使用していますということです。
  • 私がfoo()の型変数としてXを宣言しないのは、実際にクラスレベルで問題があり、このクラスの型パラメータの数を不必要に増やしたくないからです。それが動作

    public class Test 
    { 
        public interface A<X> { 
         X get(); 
         void doStuff(X x); 
        } 
        public <T extends A<?>> void foo(T t) { 
         bar(t); 
        } 
    
        private <X> void bar(A<X> t) { 
         X x = t.get(); 
         t.doStuff(x); 
        } 
    } 
    

+0

-Xlintコンパイラフラグを使用していますか?そうでない場合は、コンパイルを試してください。 –

+0

何も変わりません。 – misberner

+0

@kanに同意します。 Javaコンパイラは、実際にはこれをコンパイルします。私は1.6.0_27を使用しました。 Eclipseはあなたが与えた正確なエラーを提供しているので、おそらくそれを使用していますか? –

答えて

2

私は、コードをチェックしました。 javac 1.6.0_22。どこにエラーがありますか?または別のコードを使用していますか?

+0

ありがとうございます、仕事中の私のマシンで月曜日にチェックします、私はそこに使用しているjavacのバージョンを正確にはわかりません。私はちょうど自宅でそれをテストし、javac 1.6.0_11を使用してコンパイルしません... – misberner

+0

Btw、エラーは単に "バー(Test.A )は(T)に適用することはできません"と、マーカーbar()呼び出しを指しています。 – misberner

1

コード:

public class Test 
{ 
    public interface A<X> { 
     X get(); 
     void doStuff(X x); 
    } 
    public <T extends A<?>> void foo(T t) { 
     bar(t); 
    } 

    private <X> void bar(A<X> t) { 
     X x = t.get(); 
     t.doStuff(x); 
    } 
} 

は、Java 1.6の唯一の選択のバージョンでコンパイルします。このbugは日食のために記録されたが、スリカンスSankaranすることにより、以下の説明で拒否されました:

私は日食コンパイラの動作が正しいと JDK5とJDK7(最新)にマッチしていると信じています。 JDK6の動作は固定された 回帰であるように見えます。

基本的には、ここでは、ここで何が起こっているかを簡単に説明します:

バー(T)によって与えられるように、一般的な方法バーと呼び出しサイトを考えるには、 推論アルゴリズムはにで動作するように何の制約がありません変数の型変数Xを推測します。したがって、引き数と の期待される戻り値の型などを考慮した上で、Xはまだ解決されておらず、仕様書 は公表された下限-iと解決されます。e Xは であると推測され、その方法はボイドバー(A)tとなる。実際の のパラメータは仮パラメータに変換できないため、推測された メソッドは拒否されなければなりません。 したがって、コールは拒否されなければなりません。

コールバー((A)t);この場合、X は「#1のキャプチャ」と推測されます。この代入でパラメータ化された汎用メソッド は、パラメータの互換性が保持されるvoid bar(A)になります。

関連する問題