2012-01-21 16 views
6

は考えてみましょう:ジェネリック医薬品の名前の衝突

public interface Foo<T> { 
    public static class X{} 
    public void foobar(T t); 
} 

public class Bar<X> { 
    Foo<X> foo = new Foo<X>() { 
     public void foobar(X t) {} 
    }; 
} 

私はfoobar(X t)実装でBar<X>からXなくFoo.Xを意味することを表現する方法を発見しました。ジェネリックパラメータXの名前をBarまたは静的内部クラスの名前に変更する以外の方法はありませんか?

+2

を...することができますインターフェイス内にパブリッククラス(静的な場合でも)をネストしますか? –

+0

はい、静的内部クラスまたは汎用パラメータの名前をBarに変更すると、コンパイルされます。 – Landei

+2

@ダニエル...はいできます。それは面白く見えますが、完全に有効です。 –

答えて

9

私は型パラメータに曖昧さを持たせる方法はないと思うし、それは合理的な設計決定だと思う。

  1. 型パラメータは可能な限り1文字長でなければならず、これに対してフリップサイドは他のクラスが1文字の名前であってはならないという規則が明確です。
  2. もし明確にする能力があったなら、のタイプパラメータの名前をBar<X>に変更することが可能です()。言い換えれば、foobar(TypeParameter.X t)と言う能力があれば、タイプパラメータにX以外のものを単純に使用することができます。名前を変更すると、Xとなります。名前の衝突を避ける方法です。

タイプパラメータの名前が他のクラスに漏れないことを忘れないでください。特定の型のパラメータ名をに強制することは決してありません。したがって、言語設計者は、これが言語の複雑さを増やす価値があるとは考えていないと考えられます。

+0

私は2つ目のポイントに同意する傾向がありますが、最初のポイントでは同意しません.ClosuresやTuplesのようなかなり基本的な構文のJavaがないため、ラッパーを使用する必要があります。 'Function'や' Product'の代わりに 'F'や' P'のような名前を使うことができます(例えばhttp://www.functionaljava.org参照)。 – Landei

0

コンパイラ文句を言わないも、あなたはFoo.Xを意味している場合、あなたが何か入力された場合を除き、それは、かかわらず、TypeParameter Xを検討するかを決定するためにわざわざ:右を見ていない

public class Bar<X> { 
    Foo<X> foo = new Foo<X>() { 
     public void foobar(Foo.X t) {} 
    }; 
} 
+0

いいえ、それは当てはまりません。匿名クラスの内部では 'Foo'クラスのスコープに入っているので、' Foo.X'は外部クラスの型パラメータ 'X'をシャドウします。 – Landei

関連する問題