[英]java generic constructors
我目前有以下代碼從數據庫中檢索數據,然后創建一個User
。 我的許多classe使用此代碼來創建其他對象,如News
, Comments
等...
它使用apache commons dbutils。
final ResultSetHandler<User> handler = new ResultSetHandler<User>() {
@Override
public User handle(ResultSet rs) throws SQLException {
User user = null;
if (rs.next()) {
user = new User();
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
}
return user;
}
};
final User user = run.query(
"SELECT id, username, password FROM users WHERE username = ? AND active = 2 LIMIT 1;", handler,
username);
是否可以將QueryRunner
包裝在泛型類中並覆蓋查詢方法,以便處理程序使用ResultSet實現泛型T
我會確保任何T
類型都是接受ResultSet
的構造函數。
像這樣:
public class QueryExecuter<T> extends QueryRunner {
private ResultSetHandler<T> _handler;
public QueryExecuter(){//The T type was for testing haha
super();
handler = new ResultSetHandler<T>() {
@Override
public T handle(ResultSet rs) throws SQLException {
T object = null;
if (rs.next()) {
object = new T(rs);
}
return object;
}
};
}
}
我不知道你是否理解,但我希望如此,請問我是否需要更多細節或更好的解釋。
編輯
我以為我可以使用AbstractClass而不是所有不同對象都會擴展的泛型類型,但似乎我不能編寫一個抽象構造函數。 我是否必須創建一個返回對象實例的靜態方法,如:
public abstract class DatabaseEntity {
public static abstract DatabaseEntity create(ResultSet rs);//even this doesn't work...
}
可能,是嗎? 但這是一個壞主意。
你可以這樣做:
class ResultSetHandler<T> {
ResultSetHandler<T>(Class<T> clazz) {
this.clazz = clazz;
}
public T handle(ResultSet rs) throws SQLException {
T object = null;
if (rs.next()) {
object = clazz.getConstructor(ResultSet.class).newInstance(rs)
}
return object;
}
}
但是,混合域和數據庫是一個壞主意。 然而,更好的方法是定義一個基於結果集創建對象的abtract方法:
abstract class ResultSetHandler<T> {
protected abstract T create(ResultSet rs);
public T handle(ResultSet rs) throws SQLException {
T object = null;
if (rs.next()) {
object = create(rs);
}
return object;
}
}
然后,在您的實現類中,您只需要提供create()
方法而不是自己處理結果集,例如:
h = new ResultSetHandler<Person>() {
protected Person create(ResultSet rs) {
return new Person(rs.getString("name"));
}
}
你可以做類似的事情(通過傳遞對象的類來創建,並使用反射來調用它的構造函數),但我會發現讓POJO依賴於JDBC並且不僅知道它如何存儲在數據庫中也是不好的設計,以及在用於加載它的查詢中使用了哪些別名。
簡而言之,用戶POJO構造函數不負責處理外部未知查詢的結果集。
你可以設計一個AbstractSingleEntityHandler超類,它只有
if (rs.next()) {
阻止,並將實際的實體創建委托給抽象方法,但你不會獲得太多。
我認為在Java中不可能這樣做。 您無法在泛型中創建T
的實例。 java中的泛型不是像C ++中那樣的模板,它們只是一個object
語法糖,它會刪除強制轉換並引發編譯時警告。
在C#中沒有辦法約束T
,因此必須有一個構造函數。
如果真的有必要,最好的辦法是使用反射解析相應的類,但即使這樣你也會遇到問題,因為在調用方法時你無法知道T的運行時類 - 這個信息是從java字節碼中刪除的。 因此,您可以將類傳遞給方法,以便對其進行反射。 而且我不太確定這是一個好的設計理念。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.