繁体   English   中英

类强制转换异常泛型反射ParameterizedType

[英]Class Cast Exception Generics Reflection ParameterizedType

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

如果超类是通用类,则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;
    }
}

您收到此错误是因为EJB容器扩展了您的Stateless bean,以在方法调用时包装EJB特定的逻辑。 因此,在部署时,您会遇到以下情况:

ContainerSubclass extends SessionLogger {}

解决方案:

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

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

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

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

public class EE extends ElsAbstractCrudClass { ... }

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM