Posted by
felipeal on November 22, 2006 at 5:00 AM PST
So, here is the deal. I've created a generic DAO class that looks like the following:
package net.felipeal;
import java.util.ArrayList;
public abstract class DAO<EntityInterface, EntityImpl extends EntityInterface> {
private final Class<EntityImpl> entityClass;
public DAO( final Class<EntityImpl> clazz ) {
this.entityClass = clazz;
}
public List<EntityInterface> getEntities() {
return getObjects(this.entityClass);
}
public <TInterface, TImpl extends TInterface> List<TInterface> getObjects(Class<TImpl> clazz) {
return new ArrayList<TInterface>();
}
}
The motivation behind this class is that the sub-classes will have the getEntities() method that would return all entities managed by the DAO, and still have the getObjects() method for other entities. So, for instance, I could have something like:
package net.felipeal;
import java.util.List;
public class ProductDAO extends DAO<Product, ProductImpl> {
public ProductDAO {
super(ProductImpl.class);
}
public static void main(String[] args) {
final ProductDAO dao = new ProductDAO();
final List<Product> products = dao.getEntities();
final List<Customer> customers = dao.getObjects(CustomerImpl.class);
}
}
The code above works on Eclipse 3.2, but when I try to compile it with javac 1.5.0_09, it fails:
[felipeal@localhost src]$ javac net/felipeal/DAO.java
net/felipeal/DAO.java:15: incompatible types
found : java.util.List
required: java.util.List
return getObjects(this.entityClass);
^
1 error
So, looks like one of the two compilers is wrong: either javac should compile that code or (most likely) eclipse should have failed.
I tried a small variation that fails on Eclipse as well:
package net.felipeal;
import java.util.ArrayList;
import java.util.List;
public class DAO<EntityInterface, EntityImpl extends EntityInterface> {
private final Class<EntityImpl> entityClass;
public DAO( final Class<EntityImpl> clazz ) {
this.entityClass = clazz;
}
public List<EntityInterface> getEntities() {
final List<EntityInterface> list = getObjects(this.entityClass);
return list;
}
public <TInterface> List<TInterface> getObjects(Class<? extends TInterface> clazz) {
return new ArrayList<TInterface>();
}
}
In this class, Eclipse gives a similar error:
Type mismatch: cannot convert from List to List bug-generics/src/net/felipeal DAOB.java line 15
That makes sense, as I'm using a wildcard and so there is no way to force the returned collection to be an interface implemented by the parameterized argument.
Any clue of what's wrong (with the code, not with the design itself, please :-)? As I'm not a generics expert, I'd like to hear some comments before opening an (possibly invalid) bug on BugParade or Eclipse...