同时使用@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;
}