簡體   English   中英

java通用構造函數

[英]java generic constructors

我目前有以下代碼從數據庫中檢索數據,然后創建一個User 我的許多classe使用此代碼來創建其他對象,如NewsComments等...

它使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM