检查instanceOf后出现ClassCastException

时间:2018-06-14 10:59:35

标签: grails groovy classcastexception

我有grails(版本3.2.11)应用程序(包括groovy-2.4.11.jar)。 并遵循代码

 @CompileStatic
def removeAllErrors(DomainClass domainInstance) {
    newAssociationOperationRunnerBuilder(domainInstance)
    .setSkipChain({DomainObjectDetails<DomainObjectDataSingle> domainObjectDetails ->
        skipValidation(domainObjectDetails.currentDomain.domainObject, domainObjectDetails.associationProp?.name)})
    .build().run({DomainObjectDetails<DomainObjectDataSingle> domainObjectDetails ->
        DomainClass domain = domainObjectDetails.currentDomain.domainObject
        if (domain instanceof GormValidateable) {
            ((GormValidateable)domain).clearErrors()
        }
        if(domain instanceof WarningsHolder) {
            WarningsHolder warningsHolder = domain as WarningsHolder //<--- line 120
            Warnings warnings = warningsHolder.getWarnings()
            warnings.clearWarnings(false, true)
        }
    })
}

我正在追踪异常

2018-06-14 10:16:41,647 ERROR StackTrace - Full Stack Trace:
java.lang.IllegalArgumentException: java.lang.ClassCastException@3f6e3869
    at sun.reflect.GeneratedMethodAccessor5958.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213)
    at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1125)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
    at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:925)
    at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:908)
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:168)
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.asType(ScriptBytecodeAdapter.java:591)
    at com.webbfontaine.grails.plugins.validation.rules.DocVerificationService$_removeAllErrors_closure5.doCall(DocVerificationService.groovy:120)

任何想法可能是什么原因? 注意我也有@CompileStatic。

=============================================== ========================== 此代码的早期版本没有@CompileStatic

 def removeAllErrors(def domainInstance) {
    newAssociationOperationRunnerBuilder(domainInstance)
    .setSkipChain({DomainObjectDetails<DomainObjectDataSingle> domainObjectDetails ->
        skipValidation(domainObjectDetails.currentDomain.domainObject, domainObjectDetails.associationProp?.name)})
    .build().run({DomainObjectDetails<DomainObjectDataSingle> domainObjectDetails ->
        domainObjectDetails.currentDomain.domainObject.clearErrors()
        if(domainObjectDetails.currentDomain.domainObject instanceof WarningsHolder) {
            Warnings warnings = domainObjectDetails.currentDomain.domainObject.getWarnings()
            warnings.clearWarnings(false, true)
        }
    })
}

我得到了这个例外

com.webbfontaine.sw.sad.ci.Item cannot be cast to com.webbfontaine.sw.sad.ci.Item_$$_jvst840_3. Stacktrace follows: java.lang.ClassCastException: com.webbfontaine.sw.sad.ci.Item cannot be cast to com.webbfontaine.sw.sad.ci.Item_$$_jvst840_3
at com.webbfontaine.grails.plugins.validation.rules.DocVerificationService$_removeAllErrors_closure5.doCall(DocVerificationService.groovy:111)

1 个答案:

答案 0 :(得分:2)

您根本不应该将instanceof与代理一起使用,因为它&#39;将导致无法预测的结果。

如果要检查类的对象,可以使用isAssignableFrom()

if ( GormValidateable.isAssignableFrom( domain.getClass() ) ) {...}

isCase() / switch

switch( domain ){
  case GormValidateable: doStuff(); break
  case WarningsHolder: doOtherSTuff(); break
}