使用Class.forName()实例化单例对象?

jav*_*ld 6 java singleton constructor default instance

我想从类的字符串名称实例化一个类的一个实例.(使用Class.forName().newInstance().)

这是问题所在:我希望该实例是单例..我可以使用单例模式执行此操作,除了newInstance调用类的默认构造函数,并且使用单例,该构造函数必须是"私有"..

有解决方案吗?我可以想到一个不太优雅的方法(使用hashmap作为查找表..),但更喜欢更好的解决方案..

谢谢,

Mic*_*rdt 8

经典的单例也有一个静态的getInstance()方法 - 通过反射调用而不是使用newInstance().是的,这是更多的工作,但它是如何...

或者你可以使用setAccessible()来调用私有构造函数,但是你要破坏单例并下地狱.

第三,你可以避免单独使用Singleton并找到更好的解决方案(通常有).


ska*_*man 8

您可以使用反射来获取对类的静态工厂方法的引用,然后调用它.工厂方法可以强制执行单例模式

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

然后

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:
   }
}
Run Code Online (Sandbox Code Playgroud)

警告:单身人士设计模式可能对您的长期健康有害.


aka*_*okd 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

而且安全无虞。编辑现在有一些意义。