2

I have a little concern about generics type in non-generic classes. I'm working on an API where i have a Data Model, which has a singleton DataModelManager. This DataModelManager creates DataFactory ? extends DMAbstractObject where DMAbstractObject is an abstract class telling "i'm a DataModel class".

So basically, when i want to create an object, i use this code :

DMLine line = DataModelManager.getInstance().getDataFactory(DMLine.class).newElement();

The problem is that i'm using the function

public DataFactory<? extends DMAbstractObject> getDataFactory(Class<? extends DMAbstractObject> clazz)

So Java can't know my returned DataFactory is from the same type that my parameter clazz. Because "? extends DMAbstractObject" tells "any object extending DMAbstractObject". In a generic class, i could use : "T extends DMAbstractObject" but not here.

My DataModelManager : public class DataModelManager {

     private static DataModelManager INSTANCE;

     public static DataModelManager getInstance(){
        if(INSTANCE == null)
            INSTANCE = new DataModelManager();
        return INSTANCE;
     }  


     private HashMap<Class<? extends DMAbstractObject>, DataFactory<? extends DMAbstractObject>> dataListMap;

      /**
      * Constructor
     */
     private DataModelManager(){
        dataListMap = new HashMap<Class<? extends DMAbstractObject>, DataFactory<? extends DMAbstractObject>>();

     }

     public DataFactory<? extends DMAbstractObject> getDataFactory(Class<? extends DMAbstractObject> clazz){

         if(!dataListMap.containsKey(clazz)){
            DataFactory<? extends DMAbstractObject> dataList = new DataFactory<>(clazz);
            dataListMap.put(clazz, dataList);
            return dataList;
         }

         return dataListMap.get(clazz);


     }
 }

It's not a major issue because it's only cause a Type safety Warning (Unchecked cast from DataFactory capture#2-of ? extends DMAbstractObject to DataFactory DMLine), but i would like to know if there was a proper way to do this.

Thanks for your answers !

1 Answer 1

3
public <T extends DMAbstractObject> DataFactory<T> getDataFactory(Class<T> clazz)

use a generic to lock down the type. Generics can be defined at the method level as well as at the class level.

Sign up to request clarification or add additional context in comments.

3 Comments

Oh right, i tried some stuffs with T extends... but didn't find the good syntax to make it works and it seems to be fine with your answer ! Now i don't have to cast each time where i'm using my getDataFactory(). Thanks !
This will still require an unchecked cast at return (DataFactory<T>)dataListMap.get(clazz); I believe but it is usually safe to do for this type of thing. There is not really a better way to do it.
@Radiodef good point. Given the above code it is safe because of the conditions surrounding the dataListMap

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.