The Source for Java Technology Collaboration
User: Password:



Felipe Leme's Blog

November 2006 Archives


Who let the bugs out?

Posted by felipeal on November 22, 2006 at 05:00 AM | Permalink | Comments (4)

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...




Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds