简体   繁体   中英

java factory methods and generics

I have been cleaning up some of my code today, which involved making several factory classes for creating different classes on the fly from user input. I found they all follow an almost identical pattern:

public class MyClassFactory{
    private static MyClassFactory singleton = new MyClassFactory();
    public static MyClassFactory getInstance(){return singleton;}
    private MyClassFactory();
    private HashMap<String, Class<? extends MyClass>> instances = new HashMap<>();

    public void register(String name, Class<? extends MyClass> clazz){
        instances.put(name, clazz);
    }

    public MyClass getByName(String name) throw ...{
        return instances.get(name).newInstance();
    }
}

My Question is this, shouldn't I be able to make a super class for this, where I can pass in the class type as a generic. Something like this:

public class SimpleFactory T<Class>{
    private HashMap<String, Class<T>> instances = new HashMap<>();

    public void register(String name, Class<? extends T> clazz){
        instances.put(name, clazz);
    }
    //or possibly public <T> T getByName....
    public T getByName(String name) throw ...{
        return instances.get(name).newInstance();
    }
}

public class MyClassFactory extends SimpleFactory<MyClass.class>{
    private static MyClassFactory singleton = new MyClassFactory();
    public static MyClassFactory getInstance(){return singleton;}
    private MyClassFactory();
}

Unfortunately, I get compile errors on the whole MyClassFactory class it seems to result from the MyClass.class and sates "wrong number of arguments, required 1".

Is this possible/worthwhile?

Firstly, you have a typo on the opening line of your SimpleFactory class declaration. I think you're looking for something like

public class SimpleFactory<T> {

And then the subclass would be

public class MyClassFactory extends SimpleFactory<MyClass> {

Consider making the base class abstract.

As an aside, if your application depends a lot on singletons and has any complexity at all, or is going to continue to grow in complexity, give some consideration to using an IOC container like Spring or Guice. I'm personally a big fan a Spring. There are those who complain about its complexity, but it comes in modules and you don't have to use everything. My two cents.

You've got very wrong syntax here. I'm not 100% sure what you're after, but the following works fine:

public class SimpleFactory<T> {
    private HashMap<String, Class<? extends T>> instances = new HashMap<>();

    public void register(String name, Class<? extends T> clazz){
        instances.put(name, clazz);
    }
    //or possibly public <T> T getByName....
    public T getByName(String name) throws ... {
        return instances.get(name).newInstance();
    }
}

public class MyClassFactory extends SimpleFactory<MyClass> { ... }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM