Groovy中for循环的一个奇怪现象引出的"全局变量?"
初学Groovy,用for循环的时候出现了点问题,记录下来 环境: Eclipse4.4,Groovy编译器版本 2.3.7 Java版本:1.8_23_x86 看下面在Java中比较常见的代码 for(int?i=0,?j=0;?i<5;?i++,?j++){ ????System.out.println(i?+?",?"?+?j); } 于是我想当然的在Groovy中照着写了一个, for(int?i=0,?j++){ ????println?"$i?,?$j"); } //编译错误(具体位置在?i=0?) //unexpected?token:?=?at?line:?1,?column:?10 居然不支持,于是问了下谷姐,发现确实是不支持. 链接:?http://stackoverflow.com/questions/14535123/groovy-for-loop-with-multiple-counters 机智如我,有怎么会被区区编译错误拦住,换个方式 for(int?i=j=0;?i<5;?i++,?j++){ ????println?"$i,?$j" } //编译错误(具体位置在?,?j++) //expecting?')',?found?','?at?line:?1,?column:?24 好吧,不能j++就算了,我放循环里面去,终于可以执行了 for(int?i=j=0;?i<5;?i++){ ????println?"$i,?$j" ????j++ } //再减少一行 for(int?i=j=0;?i<5;?i=++j){ ????println?"$i,?$j" } //输出 0,?0 1,?1 2,?2 3,?3 4,?4 好了,不报错了,舒服了...那么问题来了,为什么这么可以~~~~~于是抄起字节码开看,关键位置 ?????28??goto?169 ?????31??iconst_0 ?????32??istore_2 ?????33??iload_2 ?????34??invokestatic?java.lang.Integer.valueOf(int)?:?java.lang.Integer?[67] ?????37??ldc?<Class?main.Temp>?[2] ?????39??aload_0?[this] ?????40??ldc?<String?"j">?[69] ?????42??invokestatic?org.codehaus.groovy.runtime.ScriptBytecodeAdapter.setGroovyObjectProperty(java.lang.Object,?java.lang.Class,?groovy.lang.GroovyObject,?java.lang.String)?:?void?[73] ?????45??iload_2 ?????46??istore_3?[i] ?????47??iload_3?[i] 原来如此,大概翻译过来就是(真是的更复杂点,但大概是这样的,i++这样的代码似乎变成了方法调用) ScriptBytecodeAdapter.setGroovyObjectProperty(0,?当前类class,?当前类实例,?"j"); for(int?i?=?0;?i<5;){ ????println?xxxxx ????ScriptBytecodeAdapter.setGroovyObjectProperty(PogoGetPropertySite.getProperty("j")?+?1,?"j"); ????i?=?PogoGetPropertySite.getProperty("j") } 大家可以断点试试. 那么为什么会出现这个情况了,猜测: 可能是类似于js全局变量的概念 int i = j = 0 被翻译为了 int i= 0? j = 0? 而全局变量底层实现是放在一个LinkedHashMap中的. 由于是脚本,估计j被当作全局变量类似的东西,来证明下猜想 for(int?i=j=0;?i<2;?i=++j){ ????k?=?1 ????println?"$i,?$j" } println?"$k"??//输出1 println?"$j"??//输出2 println?"$i"??//异常,?i不存在 可以看到,i的范围在for内,而j在for外也能访问,有点类似于全局变量. 最后说明下,上面的代码放在main方法里面是会报错的~~~只能实例方法中,main是静态方法. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |