2016-10-18 9 views
0

私がしようとしていることを説明する最善の方法はおそらくコードです。Javaの汎用ファクトリの実装

Public class Product 
Public class Vendor<T extends Product> 

は今、私はあなたに

Public Factory { 
     public Vendor getInstance(String Type){ 
      Class cls = Class.forName(Type); 
      return new Vendor<cls>(); 
     } 
    } 

どのように私はこの一般的な工場を作成することができるだろう文字列入力のparamに基づいてベンダーを与える一般的な工場を作成しようとしていますか?

+5

あなたはタイプセーフな方法ですることはできません。 –

+0

これはあなたのために働く依存性注入フレームワークを得ることを強く考えなければならず、やはりStringパラメータに基づいていません。 –

答えて

1

受信したパラメータに基づいてベンダーを作成する場合は、文字列の代わりにClassを使用する必要があります。また、T extends Productタイプを受け取るためにメソッドをパラメータ化することも可能です。

public class Main { 

    static class Product {} 
    static class SubProd extends Product {} 
    static class Vendor<T extends Product> {} 

    public static <T extends Product> Vendor<T> getInstance(Class<T> clazz) { 
     return new Vendor<T>(); 
    } 

    public static void main(String[] args) { 
     Vendor<SubProd> v = Main.getInstance(Main.SubProd.class); 
     System.out.println(v); 
    } 
} 

ご覧のとおり、classパラメータは直接使用されませんが、返されるベンダーのタイプを強制するために使用されます。このコードは、警告、例外、またはキャストなしでコンパイルおよび実行されます。 Stringを使用している間は、発生する可能性のあるすべての例外を処理しなければならず、おそらく醜いキャストをここやそこで行う必要があります。

ジェネリックは非常に強力です。私はこの小さな例では、何ができるのかを少しは示していると思います。ただし、問題を解決するためのよりシンプルで洗練された方法があることに注意してください。

+1

_factory_の目的は、製品クラスの具体的なインスタンスを作成することです。 _generic_ファクトリが何らかの用途に使用されているのは本当に疑問です。何らかの形で、工場は、与えられたパラメータに従ってどの具体的な製品クラスをインスタンス化するかを決定する必要があります。 _generic_ファクトリを持つということは、このロジックをどこか別の場所で実行する必要があるということです。つまり、ファクトリの_responsibility_が別の場所に移動され、汎用ファクトリが役に立たなくなります。 –

0

コンパイラはコンパイルのプロセス中に内部的にジェネリック型の情報を使用するので、これを行うことはできません。

あなたの工場にジェネリッククラス型を送信する場合があります

public class Factory { 
     public <PRODUCT extends Product> Vendor<PRODUCT> getInstance(Class<PRODUCT> productClazz){ 
      return new Vendor<PRODUCT>(); 
     } 
    } 
関連する問題