2009-08-19 10 views
9

非ジェネリッククラスのジェネリックコンストラクタを使用する利点は何ですか? Java仕様では、次のことが許可されています。ジェネリックコンストラクタの利点

クラスのタイプセーフティを強化する現実的な例を考え出すことができますか?どのようにして最初の場所でGenericを使用するよりも良いでしょう。

私は、Javaデザイナーがコンストラクタがメソッドとより一貫していることを望んでいることを理解します。 コンストラクタは、一般的なコンストラクタは、コンストラクタをするために必要な場合でしょう

<T> NonGeneric(T obj, List<T> list) { 
    list.add(obj); 
    // Don't hold a reference to list 
} 

答えて

4

私は考えることができる唯一の使用のように、その参照を保持していないいくつかのパラメータを、変異させるジェネリックを使用することができ、副作用を持つことができることを考えます汎用オブジェクトは実行中に使用しますが、完了したらそのオブジェクトは保存しませんでした。例えば

<T> NonGeneric(T[] blank, List<T> list) { 
    // Sort that list 
    T[] array = list.toArray(blank); 
    Arrays.sort(array); 

    // Pull out the values as strings 
    this.list = new ArrayList<String>(array.length); 
    for (T value : array) { 
     this.list.add(value.toString()); 
    } 
} 

それは言語設計者はそれをやってから人々を防ぐために、何の理由がなかったので、ケースの誰かが、それを望んでいただけで行うことを決めただけで何か可能性が高いです。

+0

ええ、一般的なメソッドをコンストラクタに置き換えることができます(しかし、なぜそうしたいでしょうか?)。私は実際に野生のものを見たことはありません。私のお金のために、言語が(Javaジェネリックスのバージョンを発表した後のC#のように)言語ができなかったことは複雑です。 –

0

私は同じことについて数回考えていました。

仮説的には(これはなぜそうでないのかという理由があります)、ジェネリックなコンストラクタが(ジェネリッククラス宣言のように)クラス全体の正式なジェネリック型を定義できるといいでしょう...つまり、

EntityRequestCallback extends RequestCallback 

しかし、あなたは、あなたがそれを行うことができませんでした、RequestCallbackは一般的な RequestCallback<E extends Entity>になりたかった:あなたが一般化を避けたい場合、一般的なコンストラクタは...あなたはそのクラスの一般的なフィールドを持っている。例えば

を聞かせ要求PUT/POSTの2種類だけがエンティティを使用するためです。 PUT/POST要求のコンストラクタにのみEntityパラメータが含まれています。

public class RequestCallback { 

     /** GET/DELETE requests */ 
    public RequestCallback(String gttUrl, HttpMethod method,) { 
     this.gttUrl = gttUrl; 
       this.method = method; 
    } 

     /** PUT/POST requests */ 
    public RequestCallback(String gttUrl, HttpMethod method, Entity entity) { 
     this.gttUrl = gttUrl; 
       this.method = method; 
     this.entity = entity; 
    } 
} 

しかし、あなたは、あなたが

new RequestCallback(); //without specifying generic parameter - worse than nothing 

をインスタンス化します意味しますエンティティを、持っていない要求に対するRequestCallbackを作成することになるため、クラスは、一般的なことはできませんだから、ここでの唯一の可能な方法ある一般化:あなたが持つことができるように

EntityRequestCallback<E extends Entry> extends RequestCallback 

汎用フィールド:

public E entity; 

この特定の例では、一般化は正しい選択ですが、一般化が行われない場合があります。