Reputation: 1508
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
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