简体   繁体   中英

Using java generics for a simple factory - How can I avoid these warnings

I'm trying to understand generics properly, and I've written a very simple factory, but I can' see how to get round these two warnings (I've had a good grovel around, but probably I'm not searching with the right terms). Oh! and I don't want to just supress warnings - I'm pretty sure it should be possible to do this properly .

  • Type safety: The constructor simpleFactory(Class) belongs to the raw type simpleFactory. References to generic type simpleFactory should be parameterized
  • simpleFactory is a raw type. References to generic type simpleFactory should be parameterized

All the constructs I've tried to resolve this actually fail to compile - this seems to be the closest I can get. It's the line marked ++++ that generates the warnings (on Eclipse Indigo for an android project)

I realise there are some excellent object factories around, but this is about understanding the language rather than actually making a factory ;)

Here is the source:

import java.util.Stack;

public class simpleFactory<T> {

private Stack<T> cupboard;
private int allocCount;
private Class<T> thisclass;

public static simpleFactory<?> makeFactory(Class<?> facType) {
    try {
        facType.getConstructor();
    } catch (NoSuchMethodException e) {
        return null;
    }
+++++   return new simpleFactory(facType);
}

private simpleFactory(Class<T> facType) {
    thisclass = facType;
    cupboard = new Stack<T>();
}

public T obtain() {
    if (cupboard.isEmpty()) {
        allocCount++;
        try {
            return thisclass.newInstance();
        } catch (IllegalAccessException a) {
            return null;
        } catch (InstantiationException b) {
            return null;
        }
    } else {
        return cupboard.pop();
    }
}

public void recycle(T wornout) {
    cupboard.push(wornout);
}   
}

So the important part is you actually want to capture the type of the class being passed to the factory method. I am using the same identifier (T) which hides the type of the class, which could be a little confusing so you might like to use a different identifier.

You also need to instantiate the class with a specific type, like cutchin mentioned.

public static <T> simpleFactory<T> makeFactory(Class<T> facType)
{
    try
    {
        facType.getConstructor();
    }
    catch (NoSuchMethodException e)
    {
        return null;
    }
    return new simpleFactory<T>(facType);
}

My previous answer was altogether broken. This is the better factory method.

public static <R> simpleFactory<R> makeFactory(Class<R> facType) {
    try {
        facType.getConstructor();
    } catch (NoSuchMethodException e) {
        return null;
    }
   return new simpleFactory<R>(facType);
}

Usage:

simpleFactory<String> factory = simpleFactory.makeFactory(String.class);

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