2012-07-20 128 views
2

我在堆棧上尋找了一段時間的答案。所有的答案看起來像他們說我已經有了正確的答案,但我仍然繼續在下面的構造函數中獲得第一行的類拋出異常。類拋出異常泛型反射參數化類型

SEVERE: Exception while loading the app : EJB Container initialization error 
java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType 
    at com.domain.security.logging.ElsAbstractCrudClass.<init>(ElsAbstractCrudClass.java:54) 

這是代碼。看完文檔後,我仍然無法弄清楚。我對泛型和思考比較陌生,所以需要一些幫助。 TIA。

public abstract class ElsAbstractCrudClass<T> { 
     Class<T> entity; 

     public ElsAbstractCrudClass() { 

[line 54] ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass(); 
      Type type = genericSuperclass.getActualTypeArguments()[0]; 
      this.entity = (Class<T>) type; 

     } 
    } 

這裏是抽象的CRUD類的子類(SessionLog是JPA實體):

@Stateless 
public class SessionLogger extends ElsAbstractCrudClass<SessionLog> { 

    @PersistenceContext(unitName = "ELS_Soulard_PU") 
    private EntityManager em; 
    @EJB 
    DozerInstantiator di; 
    //SessionLog entity; 
    //SessionLog sessionLog = new SessionLog(); 
    static final Logger logger = Logger.getLogger(SessionLogger.class.getSimpleName()); 

    public SessionLogger() { 
    } 
... 
+1

打印出'getClass()'和'getClass()。getGenericSuperclass()'來查看它們的效果可能很有用 – newacct 2012-07-21 02:38:30

+0

好主意。我會在今天晚些時候嘗試,也許或明天取決於時間...但我會嘗試。 – BillR 2012-07-21 17:20:26

+0

僅供參考......我的開發箱彈了一下,我正在重建......所以我還沒有試過。 :) – BillR 2012-07-25 15:18:19

回答

4

getGenericSuperclass如果超類是通用返回ParameterizedType一個實例,如果一個的Class實例不是這樣。想必你有這樣的:現在

class A extends B { ... } 
class B extends ElsAbstractCrudClass<Person> { ... } 

getClass()A.class與超B.class,這是不通用......

你可以概括你的代碼片段,只要工作的運行時類是不通用的(遞歸地遍歷類型層次結構,按照它們的定義隨時替換類型參數)。但是,除非你有幾十個CRUD類的,要求子類來傳遞正確的類對象更容易:

public abstract class ElsAbstractCrudClass<T> { 
    final Class<T> entityClass; 

    public ElsAbstractCrudClass(Class<T> entityClass) { 
     this.entityClass = entityClass; 
    } 
} 
+0

是我建立的JPA實體類。在這種情況下,我試圖使用一個SessionLog.java實體類,它包含一個沒有定義關係的單個表。我沒有任何東西可以擴展它。這會不會適合你描述的這個類別?當我完成時,我會有很多的粗俗課程,所以這就是爲什麼我想找出一個更通用的方法來做到這一點。但是,如果這開始成爲麻煩拍攝中#$ @馬拉松賽的痛點,我會回到你的建議(在子類中直接分配)。 :) – BillR 2012-07-20 21:35:43

+0

爲了更加清晰,添加了子類。 – BillR 2012-07-21 01:21:14

0

另一種方式碰到麻煩的是,如果你的繼承類使用原始類型,而不是泛型類型。換句話說,這個子類會生成你的異常,因爲它的超類型只是ElsAbstractCrudClass的原始類型。

public class EE extends ElsAbstractCrudClass { ... } 

但是這一次不會因爲它的超類型是通用型ElsAbstractCrudClass

public class EE extends ElsAbstractCrudClass<String> { ... } 
+0

你可能會看看我的第一個評論來評價答案嗎?也許它會爲你增加一些洞察力。 – BillR 2012-07-20 21:36:39

+0

對不起,我不明白你的評論。你能否提供ElsAbstractCrudClass的具體子類的前幾行的一兩個例子?也許這會有所幫助。 – 2012-07-20 21:57:04

+0

添加了一個子類來提供幫助。 – BillR 2012-07-21 01:20:40

2

你,因爲EJB容器延長您的無狀態的bean來包裝方法調用EJB特定的邏輯得到這個錯誤。因此,在部署的時候你有財產以後這樣的:

ContainerSubclass extends SessionLogger {} 

解決方案:

1)在你的構造函數首先調用

... = getClass().getSuperClass(); 
... 

2)或代碼對接口,以便EJB容器將創建動態代理通過反思。