2

我已经在 Stack 上寻找了一段时间的答案。所有的答案看起来好像他们说我已经有了正确的答案,但我仍然不断收到下面构造函数中第一行的类转换异常。

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() {
    }
...
4

3 回答 3

4

getGenericSuperclassParameterizedType如果超类是泛型的,则返回一个实例,如果不是,则返回一个实例Class。大概你有类似的东西:

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

现在,getClass()返回A.classsuperclass B.class,这不是通用的......

只要运行时类不是通用的,您就可以概括您的代码片段以使其工作(递归地遍历类型层次结构,随时用它们的定义替换类型参数)。但是,除非您有几十个 crud 类,否则要求子类传递正确的类对象更容易:

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

    public ElsAbstractCrudClass(Class<T> entityClass) {
        this.entityClass = entityClass;
    }
}
于 2012-07-20T21:03:48.063 回答
2

您收到此错误是因为 EJB 容器扩展了您的无状态 bean 以在方法调用上包装 EJB 特定逻辑。所以在部署时你有这样的事情:

ContainerSubclass extends SessionLogger {}

解决方案:

1)在您的构造函数中第一次调用

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

2) 或针对接口编写代码,以便 EJB 容器通过反射创建动态代理。

于 2013-03-18T15:09:00.450 回答
0

遇到麻烦的另一种方法是,如果您的扩展类使用原始类型,而不是泛型类型。换句话说,这个子类将生成您的异常,因为它的超类型只是原始类型 ElsAbstractCrudClass。

public class EE extends ElsAbstractCrudClass { ... }

但是这个不会,因为它的超类型是泛型类型 ElsAbstractCrudClass

public class EE extends ElsAbstractCrudClass<String> { ... }
于 2012-07-20T21:15:42.847 回答