类Cast Exception Generics Reflection ParameterizedType

时间:2012-07-20 20:51:30

标签: java generics reflection classcastexception

我已经在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() {
    }
...

3 个答案:

答案 0 :(得分: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;
    }
}

答案 1 :(得分:2)

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

ContainerSubclass extends SessionLogger {}

解决方案:

1)在构造函数中首先调用

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

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

答案 2 :(得分:0)

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

public class EE extends ElsAbstractCrudClass { ... }

但是这个不会因为它的超类型是通用类型ElsAbstractCrudClass

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