来自抽象类的Java通用子实例

时间:2017-02-23 18:55:16

标签: java generics abstract-class

我有一个抽象类,一些孩子和抽象类的通用DAO。

public abstract class Person { ... }
public class User extends Person { ... }
public class Client extends Person { ... }
public PersonDao <T extends Person> { ... }

我想在PersonDao中创建一个select方法来返回Person类的子对象。

public T select(int id) throws SQLException {
    String sql = "SELECT * FROM person WHERE per_id=?";
    PreparedStatement ps = con.preparedStatement(sql);
    ps.setInt(1, id);
    ResultSet rs = ps.executeQuery();
    T t = null;

    if(rs.next()) {
        t = new T(); // Error line

        t.setId(rs.getInt("per_id"));
        t.setName(rs.getString("per_name"));
    }

    return t;
}

如何实例化泛型子类并返回子对象?

2 个答案:

答案 0 :(得分:0)

由于Type Erasure,您无法在Java中执行此操作。您可以看到this post来解决您的问题。基本上,您必须提供您想要获得的课程。

答案 1 :(得分:0)

由于Java中的type erasure,不允许

new T()。无论如何,泛型的整个目的是在编译时确保代码中的类型安全,并且您的数据访问类不能确保,因为数据库中的条目可能对应于 a {{1或User。换句话说,SQL语句和子类之间没有映射(请注意,这通常由ORM框架(如Hibernate)处理)。解决方案是在代码中提供准确指定结果类型的其他参数。通常,Client的每个子子类都应该有自己的DAO实现(即PersonUserDao),而ClientDao方法应该是抽象的,例如:

PersonDao

如果代码可以在父public abstract class PersonDao<T extends Person> { abstract T select(int id); ... } public class UserDao extends PersonDao<User> { public User select(int id) throws SQLException { // Assuming there is a type column to differentiate between types of Person String sql = "SELECT * FROM person WHERE per_id=? and type=?"; PreparedStatement ps = con.preparedStatement(sql); ps.setInt(1, id); ps.setString(2, User.class.getName()); ResultSet rs = ps.executeQuery(); User user = null; if(rs.next()) { user = new User(); user.setId(rs.getInt("per_id")); user.setName(rs.getString("per_name")); } return user; } ... } 中共享,因为它在两个实现中都是相同的(在这种情况下,我不会在第一个中看到PersonDao泛型地方,你可以让它返回PersonDao而不是Person),然后你可以在构造函数中传递类:

T

旁注:您的代码段未显示JDBC资源的关闭方式。请务必在您的真实代码中执行此操作。