Reputation: 2212
I can't get this disentangled.
public class MySingleton<T extends AUsefulClass>{
Map<String, T> myUsefulRegistry;
private static MySingleton<T> _instance = null;
public static instance(){
if(instance == null)
_instance = new MySingleton<T>();
return _instance;
}
}
public class Test{
@Test
public void testThis(){
MySingleton<SomeClass> mySingleton = MySingleton<SomeClass>().instance();
}
}
This parametrization is faulty because you cannot make a static reference to a nonstatic T. Still, I would like to build a parameterizable singleton class.
Upvotes: 2
Views: 1095
Reputation: 4801
I'd rather look at my design in this case. Also, if you want to create a different singleton due circumstances. You'd probably use a factory to instantiate the singleton at first.
I'm not sure if the singleton pattern is a good approach, it introduces global state via objects, which is the very thing you probably don't want.
Upvotes: 0
Reputation: 7364
Here's a solution:
public class MySingleton {
private static MySingleton instance;
private final Map<String, ?> myUsefulRegistry;
private <T> MySingleton(Class<T> type) {
myUsefulRegistry = new HashMap<String, T>();
}
public static <T> MySingleton getInstance(Class<T> type) {
if (instance == null) {
instance = new MySingleton(type);
}
return instance;
}
}
If you are planning on reassigning myUsefulRegistry
, you will obviously have to omit the final modifier and also implement state based on the type
parameter (by storing it to use again).
Edit: There's an issue if the user passes a different type to the original. You may want to store the type in any case then, so you can check whether any proceeding calls to getInstance(Class<T>)
are valid.
Upvotes: 0
Reputation: 1504062
The problem is that in Java (unlike .NET) you've only got one static variable no matter how many different type arguments you provide - so MySingleton<Foo>._instance
is equal to MySingleton<Bar>._instance
.
I suspect you want a Map<Class<? extends AUsefulClass>, MySingleton>
, suppressing the warnings about raw types. Then you'd make your instance
method take a Class<T>
parameter as well, so it would know what to look up.
Of course, this is assuming you want separate state for different type arguments. If you don't need different state for MySingleton<Foo>
and MySingleton<Bar>
you can truly have a single instance, and just cast it while suppressing the unchecked conversion warning.
Upvotes: 4