2016-05-13 360 views
-2

這是星期五晚上,所以我可能會有點慢,但我無法解決我認爲這是一個簡單的問題。Java泛型和反射|如何實例化一個泛型類

我基本上有這種情況。

1)基礎類MyDAO

public abstract class MyDAO<K, E> implements DAO<K, E> 
{ 
    .... 
} 

2)一束在一個給定包MyDAO具體類實現的,說:

public class TaxonomyDAO extends MyDAO<Integer,Taxonomy>{ 

    .... 
} 

每個類延伸MyDAO基本上添加特定DAO設有relevanto到他們的E元素。我正在編寫一個通用工廠,其目標是使用反射來提供WhateverClassDAO的實例,如果此類存在,並且返回基本MyDAO,則返回基本MyDAO。我們假設K總是整數。

我已經寫了這樣的事情:

public Object getDAOForEntity(Class c) 
    { 
     createEmfa(); 

     try { 
      Class eDao = Class.forName(getClass().getPackage().getName()+c.getSimpleName()+"DAO"); 
      Constructor<?> cons = eDao.getConstructor(EntityManagerFactory.class);    
      return cons.newInstance(emfa); 
     } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { 
      Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex); 
      return new MyDAO<Integer,?????>(emfa) {}; 

     }   
    } 

這個類,給定一個Class c(說WhateverClass)嘗試使用反射來創建使用參數化構造函數的WhateverClassDAO實例。假設***DAO類與工廠中的相同包(我試圖保持足夠簡單以便在此處發佈)。

在捕獲,因爲反射失敗,我假設沒有Wha​​teverClassDAO,所以我想返回一個MyDAO<Integer,WhateverClass>,但我不能在那裏通過正確的E參數。我試圖通過Class<E>作爲一個沒有運氣的論據。我基本上想知道什麼可以替代?????。

它超出了範圍,但所有這些代碼都在Singleton EJB中。

任何幫助,即使在正確的文檔鏈接形式,將不勝感激。

+0

只有Chuck Norris可以在java中實例化一個抽象類。 – aviad

+0

好,我當之無愧 – elbuild

+0

我希望我沒有得罪。只是在開玩笑;)如果沒有這樣的DAO存在,我只會返回一個可選的缺席。 – aviad

回答

1

Class也是通用的,你可以從中推斷出正確的泛型參數:

public <E> Object getDAOForEntity(Class<E> c) { 
    try { 
     // ... 
    } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { 
     return new MyDAO<Integer,E>(emfa) {}; 
    } 
} 
+0

我以前試過,忘記在類型聲明< E >方法聲明的開始...下午7點20分...有時間休息。感謝您的快速回答:) – elbuild

+0

我要在兩分鐘內接受 – elbuild

1

你應該做一個通用的方法,也最好讓它回到你的DAO基類,而不是對象:

public <E> MyDAO<Integer, E> getDAOForEntity(Class<E> c) { 
    ... 
    try { 
     Class<MyDAO<Integer, E>> eDao = (Class<MyDAO<Integer, E>>)(Class<?>)Class.forName(getClass().getPackage().getName()+c.getSimpleName()+"DAO"); 
     Constructor<MyDAO<Integer, E>> cons = eDao.getConstructor(EntityManagerFactory.class);    
     return cons.newInstance(emfa); 
    } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { 
     return new MyDAO<Integer,E>(emfa) {}; 
    }   
    } 
+0

我回來了。在發佈之前,我很快編輯了代碼。此外,類名不是那些 – elbuild

+0

好。也可以擺脫警告,你可以添加@SuppressWarnings(「unchecked」) – yurgis