简体   繁体   English

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

[英]Class Cast Exception Generics Reflection ParameterizedType

I have looked for an answer on Stack for a while. 我已经在Stack上寻找答案了一段时间。 All the answers look like they say I already have the right answer, but I still keep getting a class cast exception for the first line in the constructor below. 所有答案看起来都像他们说的我已经有了正确的答案,但是我仍然在下面的构造函数的第一行中始终收到类强制转换异常。

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)

Here's the code. 这是代码。 After looking at the documentation I still can't figure it out. 在查看了文档之后,我仍然无法弄清楚。 I'm relatively new to generics and reflection so need some help. 我对泛型和反射比较陌生,因此需要一些帮助。 TIA. 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;

        }
    }

Here is a subclass of the abstract crud class (SessionLog is a JPA entity): 这是抽象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 returns an instance of ParameterizedType if the super class is generic, and an instance of Class if it is not. 如果超类是通用类,则getGenericSuperclass返回ParameterizedType的实例,否则则返回Class的实例。 Presumably you have something like: 大概你有这样的东西:

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

Now, getClass() return A.class with superclass B.class , which is not generic ... 现在getClass()返回A.class与超B.class ,这不是一般的...

You could generalize your code snippet to work as long as the runtime class is not generic (recursively walking the type hierarchy, replacing type parameters by their definitions as you go). 只要运行时类不是通用类,就可以使您的代码片段通用化(递归地遍历类型层次结构,随便用它们的定义替换类型参数)。 However, unless you have dozens of crud classes, requiring the subclass to pass the proper class object is easier: 但是,除非您有数十个crud类,否则要求子类传递正确的类对象会更容易:

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

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

You got this error because EJB Container extend your Stateless bean to wrap EJB specific logic on method invocation. 您收到此错误是因为EJB容器扩展了您的Stateless bean,以在方法调用时包装EJB特定的逻辑。 So at deployment time you have somthing like this: 因此,在部署时,您会遇到以下情况:

ContainerSubclass extends SessionLogger {}

Solutions: 解决方案:

1) In your constructor first call 1)在你的构造函数中第一次调用

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

2) or code against interfaces so EJB container would create Dynamic Proxy through reflection. 2)或针对接口编写代码,以便EJB容器可以通过反射创建动态代理。

Another way to run into trouble is if your extending class uses the raw type, not the generic type. 遇到麻烦的另一种方法是,如果扩展类使用的是原始类型,而不是泛型。 In other words, this subclass will generate your exception, because its supertype is simply the raw type ElsAbstractCrudClass. 换句话说,此子类将生成您的异常,因为其超类型只是原始类型ElsAbstractCrudClass。

public class EE extends ElsAbstractCrudClass { ... }

But this one will not because its supertype is the generic type ElsAbstractCrudClass 但这不是因为它的超类型是ElsAbstractCrudClass的泛型类型

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

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

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