6

クラスの文字列名からクラスの 1 つのインスタンスをインスタンス化したい。( Class.forName().newInstance(). を使用)

問題は次のとおりです。そのインスタンスをシングルトンにしたい..シングルトンパターンを使用してこれを行うことができます.ただし、 newInstance はクラスのデフォルトコンストラクターを呼び出します.シングルトンでは、そのコンストラクターは「プライベート」でなければなりません..

解決策はありますか?これを行うにはあまりエレガントではない方法を考えることもできますが (ハッシュマップをルックアップ テーブルとして使用します..)、より良い解決策を好むでしょう..

ありがとう、

4

5 に答える 5

8

従来のシングルトンには、静的な getInstance() メソッドもあります。newInstance() を使用する代わりに、リフレクションを介して呼び出します。ええ、それはもっと仕事ですが、それはそうです...

または、とにかくsetAccessible()を使用してプライベート コンストラクターを呼び出すこともできますが、シングルトンを壊して地獄に行くことになります。

第三に、Singleton を使用することを完全に回避し、より良い解決策を見つけることができます (通常は存在します)。

于 2009-07-14T20:17:48.140 に答える
8

リフレクションを使用して、クラスの静的ファクトリ メソッドへの参照を取得し、それを呼び出すことができます。ファクトリ メソッドは、シングルトン パターンを強制できます。

Class c = Class.forName("test.MyClass");
Method factoryMethod = c.getDeclaredMethod("getInstance");
Object singleton = factoryMethod.invoke(null, null);

その後

public class MyClass {

   private static MyClass instance;

   private MyClass() { 
      // private c'tor 
   }

   public static synchronized MyClass getInstance() {
      if (instance == null) {
         instance = new MyClass();
      }
      return instance:
   }
}

警告: シングルトンの設計パターンは、長期的な健康に害を及ぼす可能性があります。

于 2009-07-14T20:20:08.650 に答える
2

オブジェクトを構築するシングルトン クラスのメソッド名を知っておく必要があります。たとえば「instance()」と呼ばれる場合、次のようなことができます

Class c = Class.forName("MySingleton");
Method m = c.getDeclaredMethod("instance",null);
MySingleton singleton = m.invoke(null,null);
于 2009-07-14T20:21:33.500 に答える
1

列挙型を使用して、それぞれに HashMap という名前を付けることができます。または、依存性注入フレームワークを使用して、何かのシングルトンを取得することもできます (Guice?)

編集さて、私もコードサンプルに飛び込みます:

package tests;
public class EnumSingleton {
    public static void main(String[] args) throws Exception {
        Class<?> c = Class.forName("tests.Singleton1");
        Operation instance = Operation.class.cast(c.getEnumConstants()[0]);
        System.out.println(instance.getTHEAnswer());

        c = Class.forName("tests.Singleton2");
        instance = Operation.class.cast(c.getEnumConstants()[0]);
        System.out.println(instance.getTHEAnswer());
    }
}
interface Operation {
    int getTHEAnswer();
}
enum Singleton1 implements Operation {
    INSTANCE;
    @Override
    public int getTHEAnswer() {
        return 42;
    }
}
enum Singleton2 implements Operation {
    INSTANCE;
    @Override
    public int getTHEAnswer() {
        return 84;
    }
}

そして、その安全性と健全性。編集して、今ではいくつかの意味があります。

于 2009-07-14T20:16:19.453 に答える
0

代わりに、静的ファクトリ メソッドの存在に依存できますか? 何らかの命名規則に依存しますが、それは機能します。

結論: クラスがシングルトンであることがわかっている場合、そのクラスはそのポリシングを担当する必要があります。したがって、パターンの実装に準拠する必要があり、そのようなクラス間で動的な選択が必要な場合は、「ファクトリー」アプローチを予測できる必要があります。

于 2009-07-14T20:21:44.793 に答える