Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java generics, singletons and static methods

So I have a few 'Manager' classes, for example GroupManager. All these Managers are singletons.

Using this method for instancing:

private static GroupManager groupManager = null;

private GroupManager()
{

}

public static GroupManager Instance()
{
    if (groupManager == null)
    {
        groupManager = new GroupManager();
    }
    return groupManager;
}

I'm thinking I should start to use some inheritance as they have a lot of copied methods.

The Instance() methods for each Manager is the same.

So for inheritance i can do this (obviously):

GroupManager extends Manager

Is it possible to use generics to use the same Instance method for all managers, something like:

public class Manager<E>
{
    private static E instance = null;

    public static E Instance()
    {
        if (instance == null)
        {
            instance = new E();
        }
        return instance;
    }

}

I think that makes sense :)

So then you would do GroupManager.Instance() like normal.

like image 840
Metalstorm Avatar asked Nov 02 '11 14:11

Metalstorm


People also ask

Can generics be used with static methods?

1 Answer. You can't use a class's generic type parameters in static methods or static fields. The class's type parameters are only in scope for instance methods and instance fields.

Are static methods singletons?

A singleton doesn't use static methods, so you won't have trouble using it in a non-static context. Singletons can be extended/subclassed. Since they're objects, they can be injected into other objects, which allow for the creation of some great design patterns utilizing the concepts of dependency injection.

Are static variables singletons?

Statics are the metter of classes --> no relation with singleton pattern.

What is difference between singleton and static in Java?

The Basics Singleton is a design pattern that assures a single instance of a Class for the lifetime of an application. It also provides a global point of access to that instance. static – a reserved keyword – is a modifier that makes instance variables as class variables.


2 Answers

You don't understand how generics and statics work. If you have a static field or method (such as "instance" or instance()), which can be called without instantiating the class Manager, how do you expect the JVM (and the compiler even) to know what type E is supposed to be?

Here's an example, as per G_H's suggestion:

GeneralManager and AreaManager both extend Manager

The Manager class is the only one that has the getInstance() static method:

    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;
            }
        }
    }
like image 64
Shivan Dragon Avatar answered Oct 29 '22 20:10

Shivan Dragon


Nope, it's not gonna work. Java uses generics at compile time for type checking, but doesn't generate extra classes or retain info regarding type parameters at runtime.

When you declare Manager<E> with that type parameter E, that's something that will only play a role in an actual instance. You could have a subclass like GroupManager extends Manager<String> or whatever, but that's not magically gonna generate a variety of the static method.

Static methods and members belong with a class, not an instance. So trying to use generics there, which are intended for typing instances, isn't gonna fly.

like image 27
G_H Avatar answered Oct 29 '22 20:10

G_H