[英]Java generics, singletons and static methods
所以我有一些'经理'类,例如GroupManager。 所有这些经理都是单身人士。
使用此方法进行实例化:
private static GroupManager groupManager = null;
private GroupManager()
{
}
public static GroupManager Instance()
{
if (groupManager == null)
{
groupManager = new GroupManager();
}
return groupManager;
}
我想我应该开始使用一些继承,因为他们有很多复制的方法。
每个Manager的Instance()方法都是相同的。
所以对于继承我可以这样做(显然):
GroupManager extends Manager
是否可以使用泛型对所有管理器使用相同的Instance方法,例如:
public class Manager<E>
{
private static E instance = null;
public static E Instance()
{
if (instance == null)
{
instance = new E();
}
return instance;
}
}
我认为这是有道理的:)
那么你就像普通的那样做GroupManager.Instance()。
你不明白泛型和静态是如何工作的。 如果您有一个静态字段或方法(例如“instance”或instance()),可以在不实例化类Manager的情况下调用它,那么您希望JVM(以及编译器甚至)知道E应该是什么类型是?
根据G_H的建议,这是一个例子:
GeneralManager和AreaManager都扩展了Manager
Manager类是唯一具有getInstance()静态方法的类:
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;
}
}
}
不,它不会起作用。 Java在编译时使用泛型进行类型检查,但不会在运行时生成额外的类或保留有关类型参数的信息。
当您使用该类型参数E
声明Manager<E>
时,这只会在实际实例中发挥作用。 您可以拥有像GroupManager extends Manager<String>
这样的子类GroupManager extends Manager<String>
或者其他什么,但这并不会产生各种静态方法。
静态方法和成员属于类,而不是实例。 因此,尝试在那里使用泛型,用于打字实例,是不会飞的。
如果您按照以下方式创建组管理器类,则可以调用实例方法。
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;
}
或者,如果您知道要实例的对象,只需使该方法通用即可
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 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;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.