同时使用@CompileStatic和@Newify时的GroovyCastException

同时使用@CompileStatic和@Newify时的GroovyCastException,groovy,Groovy,为什么下面的代码会给出GroovyCastException class Main { public static void main(String... args) { Test test = new Test() } } @CompileStatic @Newify class Test { private HashMap<String, A> hashMap = [:] public Test() { set() test() }

为什么下面的代码会给出
GroovyCastException

class Main {
  public static void main(String... args) {
    Test test = new Test()
  }
}

@CompileStatic @Newify
class Test {
  private HashMap<String, A> hashMap = [:]
  public Test() {
    set()
    test()
  }
  public void test() {
    hashMap.each() { String string, A a ->
      a.printString()
    }
  }
  public void set() {
    hashMap.put("aaa", B.new("xxx"))
    hashMap.put("bbb", B.new("yyy"))
  }
}

class A {
  public String string = ""
  public void printString() {
    println(string)
  }
}

class B extends A {
  public B(String string) {
    this.string = string
  }
}
主类{
公共静态void main(字符串…参数){
测试=新测试()
}
}
@CompileStatic@Newify
课堂测试{
私有HashMap HashMap=[:]
公开考试(){
集合()
测试()
}
公开无效测试(){
hashMap.each(){String字符串,A->
a、 printString()
}
}
公共无效集(){
hashMap.put(“aaa”,B.new(“xxx”))
hashMap.put(“bbb”,B.new(“yyy”))
}
}
甲级{
public String=“”
public void printString(){
println(字符串)
}
}
B类扩展了A类{
公共B(字符串){
this.string=string
}
}
堆栈跟踪是:

Exception in thread "main" org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'main.Test@543e710e' with class 'main.Test' to class 'main.A'
  at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnSAM(DefaultTypeTransformation.java:405)
  at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnNumber(DefaultTypeTransformation.java:319)
  at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:232)
  at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.castToType(ScriptBytecodeAdapter.java:603)
  at main.Test$_test_closure1.doCall(Main.groovy:37)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:483)
  at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
  at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
  at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
  at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1019)
  at groovy.lang.Closure.call(Closure.java:426)
  at org.codehaus.groovy.runtime.DefaultGroovyMethods.callClosureForMapEntry(DefaultGroovyMethods.java:5226)
  at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2107)
  at main.Test.test(Main.groovy:36)
  at main.Test.<init>(Main.groovy:32)
  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
  at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
  at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
  at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:80)
  at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:105)
  at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:60)
  at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:235)
  at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:239)
  at main.Main.main(Main.groovy:19)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:483)
  at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
线程“main”org.codehaus.groovy.runtime.typehandling.GroovyCastException中的异常:无法强制转换对象的main。Test@543e710e“带类”main.Test“到类”main.A” 位于org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnSAM(DefaultTypeTransformation.java:405) 位于org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnNumber(DefaultTypeTransformation.java:319) 位于org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:232) 位于org.codehaus.groovy.runtime.ScriptBytecodeAdapter.castToType(ScriptBytecodeAdapter.java:603) 在main.Test$\u Test\u closure1.doCall(main.groovy:37) 在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处 位于sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中 位于java.lang.reflect.Method.invoke(Method.java:483) 位于org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93) 位于groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325) 位于org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294) 位于groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1019) 调用groovy.lang.Closure.call(Closure.java:426) 位于org.codehaus.groovy.runtime.DefaultGroovyMethods.CallClosureFormPentry(DefaultGroovyMethods.java:5226) 位于org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2107) at main.Test.Test(main.groovy:36) 测试(main.groovy:32) 位于sun.reflect.NativeConstructorAccessorImpl.newInstance0(本机方法) 位于sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 在sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 位于java.lang.reflect.Constructor.newInstance(Constructor.java:408) 位于org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:80) 位于org.codehaus.groovy.runtime.callsite.ConstructorSite$constructorsiteNounewrapnocerce.callConstructor(ConstructorSite.java:105) 位于org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:60) 位于org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:235) 位于org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:239) 在main.main.main(main.groovy:19) 在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处 位于sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中 位于java.lang.reflect.Method.invoke(Method.java:483) 位于com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) 但是当
@CompileStatic
被省略时,或者当
@Newify
被省略并且
B.new
new B
替换时,上面的代码不会出现异常并按我的预期运行。
Groovy的版本是2.4.5。

这可能是Groovy中的一个bug。你也许应该开始讨论吉拉

如果我反编译Test.Test闭包,我会看到:

public Object doCall(String string, A a) {
  ((A)ScriptBytecodeAdapter.castToType(((_test_closure1)this).getThisObject(), A.class))
    .printString();
  return null;
}
Groovy尝试将“this”转换为A,而不是变量A

如果没有
@Newify
,则生成是正确的:

public Object doCall(String k, A a) {
   a.printString();
   return null;
}

这可能是groovy中的一个bug。你也许应该开始讨论吉拉

如果我反编译Test.Test闭包,我会看到:

public Object doCall(String string, A a) {
  ((A)ScriptBytecodeAdapter.castToType(((_test_closure1)this).getThisObject(), A.class))
    .printString();
  return null;
}
Groovy尝试将“this”转换为A,而不是变量A

如果没有
@Newify
,则生成是正确的:

public Object doCall(String k, A a) {
   a.printString();
   return null;
}