簡體   English   中英

如何將泛型指定為函數參數

[英]How to specify a Generic Type as function parameter

我想為返回結果的JSE應用程序創建JPA事務。

@SuppressWarnings("unchecked")
public static <T> T transaction(EmWorker worker, Class<T>clazz){

    EntityManager em = createEntityManager();
    em.getTransaction().begin();

    //  >>> My Functional interface
    Object result = worker.work(em);

    em.getTransaction().commit();
    em.close();
    return (T)result;
}

它適用於獲取單個對象:

FunkoPop gandalf=EmFactory.transaction(   eManager -> { 
    return eManager.find(FunkoPop.class, 1);
}, FunkoPop.class);

但是現在,我想要一個FunkoPop List

List<FunkoPop> list =EmFactory.transaction(   e -> {

    String query = "SELECT f FROM FunkoPop f ";
    List<FunkoPop> l = e.createQuery(query, FunkoPop.class).getResultList();
    return l;

},  List<FunkoPop>.class);  //Won't compile ; or List.class gives warnings

transaction需要兩個參數:lambda和class。 我大概了解到,我無法捕獲類型List<FunkoPop>.class因為此參數將丟失<FunkoPop>泛型。 沒有警告的解決方案是什么?

您不能,因為沒有List<FunkoPop>類型。 全部都有一個List

但是,您可能會采用困難的方式:

List<T> transaction(EmWorker worker, Class<T>clazz) {
  ...
  List<T> l = (List<T>)e.createQuery(query, clazz).getResultList();
  return l;
}

您可能需要重命名該方法。

添加第二個功能接口以生成列表:

public static interface EmListWorker<T> {
    public List<T> work(EntityManager em);
}

public static <T> List<T> transaction(EmListWorker<T> worker, Class<T>clazz){
    EntityManager em = createEntityManager();
    em.getTransaction().begin();

    //  >>> alternative Functional interface
    List<T> result = worker.work(em);

    em.getTransaction().commit();
    em.close();
    return result;
}

使用@Holger提到的Function<EntityManager, T>很棒。 它的實現要簡單得多:沒有功能接口,也沒有骯臟的演員。 它返回一個檢查的類型。

實現方式:

public static <T> T transaction(Function<EntityManager,T> worker){

    EntityManager em = createEntityManager();
    em.getTransaction().begin();

    T result = worker.apply(em);

    em.getTransaction().commit();
    em.close();

    return result;
}

用法:

    FunkoPop gandalf = new FunkoPop("Gandalf");

    EmFactory.transaction( em -> {
        em.persist(gandalf);
        return gandalf;
    });

    List<FunkoPop> list =EmFactory.transaction( em -> {
        String query = "SELECT f FROM FunkoPop f ";
        return  em.createQuery(query, FunkoPop.class).getResultList();
    });

暫無
暫無

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

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