簡體   English   中英

Java泛型:如何從方法中獲取泛型類型?

[英]Java generics: how to get a generic type from a method?

雖然我的問題是關於Java泛型,但我已經提出了一些與JPA相關的代碼來向您展示真實的上下文。

我正在使用JPA 2.0和基於Criteria API的查詢。 我的所有查詢都遵循相同的模式(比較簡單的屬性;不需要路徑導航),所以我正在嘗試編寫一個泛型類來處理JPA,同時將業務邏輯保持在單獨的類中。 我的目標是有一個方法,給定一個實體類型和一個存儲定義條件的對(字段名稱 - >期望值)的Map,返回一個bean(或bean的集合),其中包含一些實體字段的值。

我所有的實體實施Persistible接口,而我所有的傳輸對象繼承QueryBean 我認為這些類與問題無關,所以我正在跳過他們的代碼。

以下代碼是我的第一個方法的片段(請假設cb是有效的CriteriaBuilder實例):

protected <T extends QueryBean, TT extends Persistible> Collection<T> executeQueryEntity
        (Class<T> type, Class<TT> rootType, QueryConfig queryConfig, Map<String, Object> parameters) {
    // (...) Initialization goes here

    CriteriaQuery<T> c = cb.createQuery(type);

    // FROM CLAUSE
    Root<TT> root = c.from(rootType);

    // SELECT CLAUSE
    List<String> constructorParams = queryConfig.getTargetAttributes();
    Selection<?>[] selectArray = new Selection<?>[constructorParams.size()];
    for (int i = 0; i < constructorParams.size(); i++) {
        selectArray[i] = root.get(constructorParams.get(i));
    }
    c.select(cb.construct(type, selectArray));

    // WHERE CLAUSE
    for (String filter : parameters.keySet()) {
        if (queryConfig.getFieldConfiguration().get(filter).compareUsingEquals()) {
            // SOME PREDICATE
        }
        else {
            // SOME OTHER PREDICATE
        }
    }

    // (...) Rest of the code goes here
}

我的QueryConfig界面如下:

public interface QueryConfig {

List<String> getTargetAttributes();
Map<String, FieldConfiguration> getFieldConfiguration();

}

由於我已經在使用QueryConfig類來提供有關查詢的信息(例如QueryBean構造函數所需的參數或有關實體字段的信息),我認為從該類獲取實體類型而不是傳遞它會很好作為Class參數。 我從這個問題推斷它不能直接完成,所以我嘗試了以下解決方法:

像QueryConfig一樣添加方法:

Class< ? extends Persistible> getTargetEntity();

添加這樣的中間方法:

public <T extends QueryBean> Collection<T> queryMany(Class<T> type, QueryConfig config, Map<String, Object> parameters) {
    executeQueryEntity(type, config.getTargetEntity(), parameters);
}

但它不會編譯。 我相信原因在這里解釋: Class Generics的類型不匹配但我實際上不理解答案。 我的問題是:有沒有辦法避免將Class< TT >參數傳遞給execute方法? 這是處理問題的好方法還是我應該重構整個問題? 對代碼的任何改進也是受歡迎的!

我不太明白你認為你的方法會起作用的原因: QueryConfig with Class< ? extends Persistible> getTargetEntity(); Class< ? extends Persistible> getTargetEntity(); 不提供編譯器可以引用的類型信息,為什么你認為編譯器可以“猜測”你要返回的類型,並為你做類型檢查?

您可以采取的一種方法是在QueryConfig中提供類型信息

public interface QueryConfig <T extends Persistable> {
  Class<T> getTargetEntity();
  List<String> getTargetAttributes();
  Map<String, FieldConfiguration> getFieldConfiguration();
}

你的queryMany方法可以像:

public <T extends QueryBean, TT extends Persistible> 
Collection<T> queryMany(Class<T> type, 
                        QueryConfig<TT> config, 
                        Map<String, Object> parameters) {
    executeQueryEntity(type, config.getTargetEntity(), parameters);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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