javaspring-bootmavenincompatibletypeerror

'incompatible types error' occured when compiling Java code


it's a Spring Boot application. I don't know how to make the code compile correctly.

public class JavassistGenerator implements Generator {
    @SuppressWarnings("unchecked")
    @Override
    public <T extends Enum, C extends UntypedStateMachine> Class<C> gen(Class<T> eventType) throws Exception {

        ClassPool pool = ClassPool.getDefault();
        ClassClassPath classPath = new ClassClassPath(this.getClass());
        pool.insertClassPath(classPath);
        CtClass cc = pool.makeClass(eventType.getName() + "$StateMachine");
        ClassFile ccFile = cc.getClassFile();
        ConstPool constPool = ccFile.getConstPool();

        //继承
        cc.setSuperclass(pool.get("com.youzan.pay.hvp.common.sm.generator.AbstractStateMachineExt"));

        // 添加类注解
        AnnotationsAttribute bodyAttr = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
        Annotation bodyAnnot = new Annotation("org.squirrelframework.foundation.fsm.annotation.StateMachineParameters", constPool);
        bodyAnnot.addMemberValue("stateType", new ClassMemberValue("java.lang.String", constPool));
        bodyAnnot.addMemberValue("eventType", new ClassMemberValue(eventType.getName(), constPool));
        bodyAnnot.addMemberValue("contextType", new ClassMemberValue(BizContextParam.class.getName(), constPool));
        bodyAttr.addAnnotation(bodyAnnot);
        ccFile.addAttribute(bodyAttr);
        return cc.toClass();// error occur this line 
    }
}

Error message:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project pay-hvp-common: Compilation failure
[ERROR] /Users/ykwoo001/Documents/work/codes/pay-hvp/pay-hvp-common/src/main/java/com/youzan/pay/hvp/common/sm/generator/JavassistGenerator.java:[42,26] 不兼容的类型: java.lang.Class<capture#1, 共 ?>无法转换为java.lang.Class<C>
[ERROR] -> [Help 1]

Solution

  • CtClass#toClass returns a Class<? > (at compile-time), no matter what superclass you set using CtClass#setSuperClass, the compiler does not know the actual superclass.

    At runtime, the generated class is a subtype of AbstractStateMachineExt but not at compile-time.

    You have two options for fixing this.

    You could either just return a Class<? >:

    public <T extends Enum> Class<?> gen(Class<T> eventType) throws Exception {
    

    or use an unchecked cast:

    return (Class<C>) cc.toClass();