返回两个或多个泛型类型的Java方法

时间:2017-08-15 01:01:33

标签: java generics

关于返回泛型类型的Java方法有很多问题,但到目前为止它们都没有帮助我。

所以这是我的代码:

interface DAO<K, T> {
   void    insert(T t);
   void    update(K k, T t);
   void    delete(K k);
   void    delete();
   T       select(K k);
   List<T> select();
}

public class CourseDAO implements DAO<String, Course> {
   public void         insert(Course t) {}
   public void         update(String k, Course t) {}
   public void         delete(String k) {}
   public void         delete() {}
   public Course       select(String k) {}
   public List<Course> select() {}
}

public class StudentDAO implements DAO<Long, Student> {
   public void          insert(Student t) {}
   public void          update(Long k, Student t) {}
   public void          delete(Long k) {}
   public void          delete() {}
   public Student       select(Long k) {}
   public List<Student> select() {}
}

public enum EntityType { COURSE, STUDENT }

现在我想要一个接受EntityType参数的工厂方法,并根据参数值返回CourseDAOStudentDAO的实例。

我尝试了以下代码但没有成功:

public <K,T> DAO<K,T> createDAOFactory(EntityType type) {
   switch (type) {
      case COURSE  : return (K,T) new CourseDAO();  break;
      case STUDENT : return (K,T) new StudentDAO(); break;
   }
   return null;
}

有没有人可以帮我写作和调用这个方法???

干杯,
罗穆阿尔。

2 个答案:

答案 0 :(得分:1)

您正在寻找的演员是(DAO<K,T>)。但是你会收到警告,因为泛型擦除会使它不安全。 switch工厂的另一个固有风险是,当您添加新的case时,您可能会忘记创建相应的EntityType。更安全的替代方案是使用泛型类型重新定义EntityType,并让它成为工厂。不幸的是,使用正确的枚举不可能,但您可以像这样模拟它:

abstract class EntityType<K, T> {
    public abstract DAO<K, T> createDAO();

    public static final EntityType<String, Course> COURSE = new EntityType<String, Course>() {
        @Override
        public DAO<String, Course> createDAO() {
            return new CourseDAO();
        }
    };
    public static final EntityType<Long, Student> STUDENT = new EntityType<Long, Student>() {
        @Override
        public DAO<Long, Student> createDAO() {
            return new StudentDAO();
        }
    };
}

或者您可以使用lambdas来减少样板:

class EntityType<K, T> {
    private final Supplier<DAO<K, T>> constructor;

    private EntityType(Supplier<DAO<K, T>> constructor) {
        this.constructor = constructor;
    }

    public DAO<K, T> createDAO() {
        return constructor.get();
    }

    public static final EntityType<String, Course> COURSE = new EntityType<>(CourseDAO::new);
    public static final EntityType<Long, Student> STUDENT = new EntityType<>(StudentDAO::new);
}

现在,您只需拨打createDAOFactory(EntityType.COURSE)

,而不是拨打EntityType.COURSE.createDAO()

答案 1 :(得分:0)

也许你可以这样做?

public class StudentDAO<Long,Student> implements DAO<Long, Student> {
    public void          insert(Student t) {}
    public void          update(Long k, Student t) {}
    public void          delete(Long k) {}
    public void          delete() {}
    public Student       select(Long k) {return null;}
    public List<Student> select() {return null;}
}

public <K,T> DAO<K,T>createDAOFactory(EntityType type) {
    switch (type) {
        case COURSE  : return new CourseDAO();
        case STUDENT : return new StudentDAO();
    }
    return null;
}

第一个回答

您不需要使用泛型,因为实现类已指定了类型。

public DAO createDAOFactory(EntityType type) {
    switch (type) {
        case COURSE  : return new CourseDAO();
        case STUDENT : return new StudentDAO();
    }
    return null;
}