user1781028
user1781028

Reputation: 1508

Java - Factory and Strategy Patterns with Generics

I'm trying to implement a Strategy + Factory pattern using generics. The goal is to return to a client class an implementation of the interface DocumentDao that can deal with a type T extends Document, so I've multiple Dao interface extending DocumentDao for different subtypes of Document.

Here is my code:

public class Document { ... }

public class DocumentA extends Document { ... }

public class DocumentB extends Document { ... }

public interface DocumentDao<T extends Document> {
   public void update(T document);
}

public interface DocumentADao<DocumentA> {}

public interface DocumentDaoFactory {
   public <T extends Document> DocumentDao<T> getDaoInstance(Class<T> clazz);
}

Then I try to use the Factory:

private <T extends Document> void someMethod(T document) {
   ...
   DocumentDao<T> documentDao = this.documentDaoFactory.getDaoInstance(document.getClass());
   documentDao.update(document);
   ...
}

But the compiler complaints about the getDaoInstance() call:

Type mismatch: cannot convert from DocumentDao<? extends AbstractGDriveDocument<?>> to DocumentDao<T>

How to deal with this situation? How can I obtain a similar solution?

Thanks

Upvotes: 1

Views: 964

Answers (1)

Makoto
Makoto

Reputation: 106430

The problem is that getClass is returning a Class<?>, which is appropriate for the API; it would not know what specific Class instance to bring back. Additionally, your type bound is incorrect and invalid in your method.

To fix this, you would need to change two things:

  • In your DocumentDaoFactory method, change the bound to be appropriate.

    <T extends Document> DocumentDao<T> getDaoInstance(Class<T> clazz);
    
  • In your use of getDaoInstance, perform an unchecked cast to Class<T>.

    DocumentDao<T> documentDao = this.documentDaoFactory.getDaoInstance((Class<T>) document.getClass());
    

The way that your types are bound should give you back the instances you care about, without getting any runtime errors.

Upvotes: 4

Related Questions