2011-11-02 13 views
7

私はGroupManagerのようないくつかの 'マネージャ'クラスを持っています。これらのマネージャはすべてシングルトンです。Javaジェネリック、シングルトン、静的メソッド

インスタンス化のために、この方法を使用する:私は考えている

private static GroupManager groupManager = null; 

private GroupManager() 
{ 

} 

public static GroupManager Instance() 
{ 
    if (groupManager == null) 
    { 
     groupManager = new GroupManager(); 
    } 
    return groupManager; 
} 

私は、彼らがコピーされたメソッドの多くを持っているとして、いくつかの継承を使用することを開始する必要があります。

各ManagerのInstance()メソッドは同じです。私は(明らかに)これを行うことができ、継承のためにそう

GroupManager extends Manager 

のようなもの、すべての管理職のための同じインスタンスメソッドを使用するためにジェネリックを使用することが可能です:私は考えて

public class Manager<E> 
{ 
    private static E instance = null; 

    public static E Instance() 
    { 
     if (instance == null) 
     { 
      instance = new E(); 
     } 
     return instance; 
    } 

} 

それは理にかなっています:)

それでは、GroupManager.Instance()は通常のように行います。

+1

Javaのジェネリックを使用して欠場しない場合のみ、その細かいので、静的コンテキストで使用されない方法でありますC++テンプレートと同じ!手放す! Java Genericを使用してオブジェクトを割り当てることはできません(つまり、newを呼び出すことはできません)。 "Java Type Erasure"のgoogle検索を試してください – DwB

+0

関連:http://stackoverflow.com/questions/1927789/why-should-i-care-that-java-doesnt-have-reified-generics – BalusC

+0

マネージャ Eはジェネリック型への参照。実行時にのみ既知の型のオブジェクトを割り当てるようにクラスを設定する簡単な方法はありません。 Reid Macの答えは私が試みるものです。 – DwB

答えて

9

あなたはジェネリックスと統計がどのように機能するか分かりません。クラスマネージャをインスタンス化せずに呼び出すことができる静的なフィールドまたはメソッド( "instance"やinstance()など)がある場合、JVM(およびコンパイラの偶数)あれ?ここ

はG_Hの提案に従って、例えば次のとおり

public class Manager { 

     private static Map<Class<? extends Manager>,Manager> INSTANCES_MAP = new java.util.HashMap<Class<? extends Manager>, Manager>(); 

//Also, you will want to make this method synchronized if your application is multithreaded, 
//otherwise you mihgt have a race condition in which multiple threads will trick it into 
//creating multiple instances 
     public static <E extends Manager> E getInstance(Class<E> instanceClass) throws InstantiationException, IllegalAccessException { 
      if(INSTANCES_MAP.containsKey(instanceClass)) { 
       return (E) INSTANCES_MAP.get(instanceClass); 
      } else { 
       E instance = instanceClass.newInstance(); 
       INSTANCES_MAP.put(instanceClass, instance); 
       return instance; 
      } 
     } 
    } 
+1

ええ、それはシングルトンを実装するという考えではまったく機能しません。 'Class'esからインスタンスへのMapのようなひどく歪んだ構造が必要です。 –

+0

+1、それは本当ですが、私はその観察を追加するかどうかを考えていました(私は、最初にジェネリックと静的の基本概念を理解してからこのように使う必要があると信じさせないことにしました)。しかし、あなたは良い点を作る。さらに、汎用EタイプをE extends RootOfIheritanceChainClassのような基本クラスに制限することができます。 –

+0

私はちょっと忘れてしまいました。私はちょうど一緒に行くべきです:基本的には、新しいマネージャごとに新しいInstance()メソッドが必要です。 – Metalstorm

2

ゼネラルマネージャーとAreaManager両方マネージャクラスはのgetInstance()静的メソッドを持っている唯一のものであるマネージャー

を拡張しますいいえ、それはうまくいかないでしょう。 Javaは型チェックのためにコンパイル時にジェネリックスを使用しますが、実行時に余分なクラスを生成したり型パラメータに関する情報を保持したりすることはありません。

Manager<E>をその型パラメータEで宣言すると、実際のインスタンスでのみ役割を果たすことになります。あなたはGroupManager extends Manager<String>のようなサブクラスを持つことができますが、それは魔法のようにさまざまな静的メソッドを生成するつもりはありません。

静的メソッドおよびメンバーは、インスタンスではなくクラスに属します。だから、そこにジェネリックスを使用しようとしていますが、それはインスタンスをタイプすることを意図しています。

0

次のようにグループマネージャークラスを作成すると、インスタンスメソッドを呼び出すことができます。あなたがのためにインスタンスをしたいオブジェクトを知っていれば、単に一般的な方法私は港

public static <T> T getInstance(Class<T> t){ 
      try { 
      return t.newInstance(); 
     } catch (InstantiationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IllegalAccessException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     return null; 
    } 

をしたり、

public class GroupManager extends Manager<GroupManager>{} 

そして、あなたのマネージャークラスがこれを試す中 ...

public class Manager<E> 
{ 
private static E instance = null; 

public static E Instance() 
{ 
        try { 
      return instance.newInstance(); 
     } catch (InstantiationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IllegalAccessException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     return null; 
} 

これがうまくいくかどうかは分かりません。

+1

最初の例が間違っています – Fabian

0

汎用コンテキストでコンストラクタを挿入します。現金はスレッドセーフではありませんが、

public class Example { 

    public static class MySingletonClass { 
    } 

    public interface Provider<T> { 
     T get(); 
    } 

    static final Provider<MySingletonClass> myClassInstanceProvider = new Cash<MySingletonClass>(new Provider<MySingletonClass>() { 
      @Override 
      public MySingletonClass get() { 
       return new MySingletonClass(); 
      } 
     }); 


    public static class Cash<T> implements Provider<T> { 
     private Provider<T> provider; 

     public Cash(Provider<T> provider) { 
      this.provider = provider; 
     } 

     @Override 
     public T get() { 

      final T t = provider.get(); 
      provider = new Provider<T>() { 

       @Override 
       public T get() { 
        return t; 
       } 
      }; 
      return t; 
     } 
    } 
} 
0

public class Manager<E>{ 

private static Object instance = null; 

    public static E Instance() { 
     if (instance == null) 
     { 
     instance = new E(); 
     } 
     return (E)instance; 
    } 
} 

+0

上記の答えはしますか? –

+0

これはうまくいきません – Fabian

+0

それはうまくいきません... – mahieddine

関連する問題