我有一个抽象类,一些孩子和抽象类的通用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;
}
如何实例化泛型子类并返回子对象?
答案 0 :(得分:0)
由于Type Erasure,您无法在Java中执行此操作。您可以看到this post来解决您的问题。基本上,您必须提供您想要获得的课程。
答案 1 :(得分:0)
new T()
。无论如何,泛型的整个目的是在编译时确保代码中的类型安全,并且您的数据访问类不能确保,因为数据库中的条目可能对应于 a {{1或User
。换句话说,SQL语句和子类之间没有映射(请注意,这通常由ORM框架(如Hibernate)处理)。解决方案是在代码中提供准确指定结果类型的其他参数。通常,Client
的每个子子类都应该有自己的DAO实现(即Person
和UserDao
),而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资源的关闭方式。请务必在您的真实代码中执行此操作。