java 使用 Class.forName() 实例化单例对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1127716/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Instantiate singleton object using Class.forName()?
提问by javaphild
I want to instantiate one instance of a class from the string name of the class. ( using Class.forName().newInstance(). )
我想从类的字符串名称实例化一个类的实例。(使用 Class.forName().newInstance()。)
Here's the problem: I want that instance to be a singleton.. I could do this using a singleton pattern, except that newInstance calls the default constructor for a class, and with a singleton, that constructor must be "private"..
问题是:我希望该实例成为单例。我可以使用单例模式来做到这一点,除了 newInstance 调用类的默认构造函数,并且对于单例,该构造函数必须是“私有的”。
Is there a solution? I could think of a less elegant way to do this (using a hashmap as a lookup table..), but would prefer a better solution..
有解决办法吗?我可以想到一种不太优雅的方法来做到这一点(使用哈希图作为查找表..),但更喜欢更好的解决方案..
Thanks,
谢谢,
回答by Michael Borgwardt
A classic singleton also has a static getInstance() method - call that via reflection instead of using newInstance(). Yeah, it's more work, but that's how it is...
一个经典的单例也有一个静态的 getInstance() 方法——通过反射而不是使用 newInstance() 调用它。是的,这是更多的工作,但就是这样......
Or you could use setAccessible()to call the private constructor anyway, but you'd break the singleton and go to hell.
或者您无论如何都可以使用setAccessible()来调用私有构造函数,但是您会破坏单例并见鬼去。
Thirdly, you could avoid having a Singleton altogether and find a better soltion (there usually is).
第三,您可以完全避免使用单例并找到更好的解决方案(通常有)。
回答by skaffman
You could use reflection to get a reference to a static factory method of the class, and then invoke that. The factory method could enforce the singleton pattern
您可以使用反射来获取对类的静态工厂方法的引用,然后调用它。工厂方法可以强制执行单例模式
Class c = Class.forName("test.MyClass");
Method factoryMethod = c.getDeclaredMethod("getInstance");
Object singleton = factoryMethod.invoke(null, null);
And then
接着
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:
}
}
Warning: Singleton design pattern may be detrimental to your longterm health.
警告:单例设计模式可能对您的长期健康有害。
回答by nos
You'll have to know the method name of your singleton class that constructs the object. If it's e.g. called "instance()" you can do something like
您必须知道构造对象的单例类的方法名称。如果它被称为“实例()”,你可以做类似的事情
Class c = Class.forName("MySingleton");
Method m = c.getDeclaredMethod("instance",null);
MySingleton singleton = m.invoke(null,null);
回答by akarnokd
You could use an enum and have a HashMap named for each of them. Or you could use some dependency injection framework to get a singleton of something (Guice?)
您可以使用枚举并为每个枚举命名一个 HashMap。或者你可以使用一些依赖注入框架来获得一些东西(Guice?)
EditOkay, I jump in with a code sample too:
编辑好的,我也加入了一个代码示例:
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;
}
}
And its safe and sound. EditAnd has some meaning now.
并且它安全无恙。编辑现在有一些意义。
回答by djna
Can you instead rely upon the existence of a static factory method? It would rely upon some manner of naming convention, but that would work.
你可以依赖静态工厂方法的存在吗?它将依赖于某种命名约定,但这会起作用。
Bottom line: if a class is to be known to be singleton then it must have responsibility for that policing. Hence it must conform to some implementation of the pattern, and if you want a dynamic selection amongst such classes then you need to be able to predict the "Factory" approach.
底线:如果一个类被称为单例,那么它必须负责监管。因此,它必须符合模式的某些实现,并且如果您想要在此类类中进行动态选择,那么您需要能够预测“工厂”方法。

