Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to create a generic singleton class in java?

Tags:

java

generics

i want to create a generic singleton class in java witch gives singleton object of class which i pass in method parameter. some thing like below code : please help

public final class Listener<T extends Object>  {
    private Listener() {
    }

    public static <T> Listener<?> getInstance(Class<T> clazz) {
        return SingletonHolder.INSTANCE;
    }

    private static class SingletonHolder {
        public static final Listener INSTANCE = new Listener();
        // private static final Map<Class<? extends Runnable>,Listener<? extends
        // Runnable> INSTANCE = new ...;
    }
}
like image 519
saurabhking Avatar asked Aug 02 '12 06:08

saurabhking


People also ask

How do you create a generic class?

To update the Box class to use generics, you create a generic type declaration by changing the code "public class Box" to "public class Box<T>". This introduces the type variable, T, that can be used anywhere inside the class. As you can see, all occurrences of Object are replaced by T.

How would you create a singleton?

To create the singleton class, we need to have static member of class, private constructor and static factory method. Static member: It gets memory only once because of static, itcontains the instance of the Singleton class. Private constructor: It will prevent to instantiate the Singleton class from outside the class.

Can we initialize singleton class?

To create a singleton class using Eager Initialization method, we need to follow the below steps: Declare the constructor of the class as private. Now, create a private class member for this Singleton class. In the next step, you need to define a factory method that will return the object of the Singleton class.


4 Answers

Make an enum with just one value, INSTANCE or such. Instant singleton.

If I understand you correctly, I think you want your singleton to implement some generic interface? Something like:

interface ListenerInterface<T> {
    void handleEvent(T event);
}

In that case, you can use an unchecked cast to return your enum-as-singleton in a generified way. This is safe as long as your singleton doesn't actually use the instance (or else, only assume it's an Object).

public enum MySingleton implements ListenerInterface<Object> {
    INSTANCE;

    @SuppressWarnings("unchecked")
    public static <T> ListenerInterface<T> getListener() {
        return (ListenerInterface<T>) INSTANCE;
    }

    public void handleEvent(Object event) {
        System.out.println("I am a singleton. An event happened: " + event);
    }

}

If the interface is a producer instead of consumer -- that is, it returns a T -- then you can only return null safely. Otherwise, someone else will get a ClassCastException when they try to use their T, which they think is a Foo but is actually just an Object.

like image 60
yshavit Avatar answered Oct 04 '22 17:10

yshavit


This was going to be comment but I think it better be an answer due to character limit,

Thinking little bit deeper will it be really possible to create a generic singleton class?

A singleton class can not be instantiated neither should it be cloned.

To give any class this behavior you will have to make all the constructors private and clone method will have to be overridden to throw an exception. Now if you are going to change all your classes to implement this behavior is your way of creating singleton really generic?

Please excuse me if I interpreted the question wrongly

like image 38
Sap Avatar answered Oct 04 '22 17:10

Sap


You can do something like this, but is unreliable IMHO:

public class SimpleSingleton {
private Map<String, Object> counter = new HashMap<String, Object>();

public <T> T getInstance(Class<T> clazz) throws IllegalAccessException, InstantiationException {
    T singleton = (T) counter.get(clazz.getName());
    if (singleton == null) {
        singleton = clazz.newInstance();
        counter.put(clazz.getName(), singleton);
    }
    return singleton;
}

}

like image 43
Random42 Avatar answered Oct 04 '22 15:10

Random42


The solution for me to this problem was designing it like this:

public interface IListener<T extends Object>  {
    void handle(T event);
}

public final class Listener implements IListener<Object> {
    private static Listener instance = new Listener();

    private Listener() {
    }

    public static Listener getInstance() {
        return instance;
    }

    @Override
    public void handle(Object event) {
        //TODO Do stuff
    }
}
like image 32
Laurentiu Stamate Avatar answered Oct 04 '22 16:10

Laurentiu Stamate