jav*_*ld 6 java singleton constructor default instance
我想从类的字符串名称实例化一个类的一个实例.(使用Class.forName().newInstance().)
这是问题所在:我希望该实例是单例..我可以使用单例模式执行此操作,除了newInstance调用类的默认构造函数,并且使用单例,该构造函数必须是"私有"..
有解决方案吗?我可以想到一个不太优雅的方法(使用hashmap作为查找表..),但更喜欢更好的解决方案..
谢谢,
经典的单例也有一个静态的getInstance()方法 - 通过反射调用而不是使用newInstance().是的,这是更多的工作,但它是如何...
或者你可以使用setAccessible()来调用私有构造函数,但是你要破坏单例并下地狱.
第三,你可以避免单独使用Singleton并找到更好的解决方案(通常有).
您可以使用反射来获取对类的静态工厂方法的引用,然后调用它.工厂方法可以强制执行单例模式
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)
警告:单身人士设计模式可能对您的长期健康有害.
您可以使用枚举并为每个枚举命名一个 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)
而且安全无虞。编辑现在有一些意义。