「原创声明:保留所有权利,禁止转载」
之前写过一些Groovy 重载操作符(终极版)的文章,中间用了内部的枚举类,然后通过一个static HPS getInstance(char c)
方法获取不同的枚举对象,今天想着把中间的字符去掉,放在枚举类属性中。却发现了一个错误,又是一顿操作猛如虎,重启缓存二百五。
经过多方求证失败后,我开始还原代码,一点点点排查,终于找到了问题的症结所在。下面分享一下这个坑。
错误的代码
package com.fun.ztest.groovy
import com.fun.moco.MocoServer
class MocoDemo extends MocoServer {
public static void main(String[] args) {
println FunTester.FUN
}
static enum FunTester {
FUN('3'),TESTER('2')
char name
FunTester(char name) {
this.name = name
}
}
}
然后运行,控制台输出:
INFO-> 当前用户:fv,IP:10.60.131.54,工作目录:/Users/fv/Documents/workspace/fun/,系统编码格式:UTF-8,系统Mac OS X版本:10.16
Exception in thread "main" java.lang.ExceptionInInitializerError
at sun.misc.Unsafe.ensureClassInitialized(Native Method)
at sun.reflect.UnsafeFieldAccessorFactory.newFieldAccessor(UnsafeFieldAccessorFactory.java:43)
at sun.reflect.ReflectionFactory.newFieldAccessor(ReflectionFactory.java:142)
at java.lang.reflect.Field.acquireFieldAccessor(Field.java:1088)
at java.lang.reflect.Field.getFieldAccessor(Field.java:1069)
at java.lang.reflect.Field.get(Field.java:393)
at org.codehaus.groovy.reflection.CachedField.getProperty(CachedField.java:55)
at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:1804)
at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:3797)
at org.codehaus.groovy.runtime.callsite.ClassMetaClassGetPropertySite.getProperty(ClassMetaClassGetPropertySite.java:50)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:298)
at com.fun.ztest.groovy.MocoDemo.main(MocoDemo.groovy:10)
Caused by: groovy.lang.GroovyRuntimeException: Could not find matching constructor for: com.fun.ztest.groovy.MocoDemo$FunTester(String, Integer, String)
at groovy.lang.MetaClassImpl.createCachedConstructor(MetaClassImpl.java:1613)
at groovy.lang.MetaClassImpl.selectConstructorAndTransformArguments1(MetaClassImpl.java:1639)
at groovy.lang.MetaClassImpl.selectConstructorAndTransformArguments(MetaClassImpl.java:1561)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.selectConstructorAndTransformArguments(ScriptBytecodeAdapter.java:250)
at com.fun.ztest.groovy.MocoDemo$FunTester.$INIT(MocoDemo.groovy)
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:497)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:101)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite.invoke(StaticMetaMethodSite.java:44)
at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite.callStatic(StaticMetaMethodSite.java:100)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:55)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:196)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:224)
at com.fun.ztest.groovy.MocoDemo$FunTester.<clinit>(MocoDemo.groovy)
... 12 more
Process finished with exit code 1
乍一看,都是什么神仙错误,居然是初始化异常,而且重点是异常信息Could not find matching constructor for: com.fun.ztest.groovy.MocoDemo$FunTester(String, Integer, String)
,我始终无法想清楚我在哪里用了这个构造方法。
原因剖析
经过一点点点还原代码,终于发现是添加枚举对象的时候报错的,再一想,Groovy
里面对于双引号""
和单引号‘’
是不区分char
和String
的,应该是这个原因导致枚举类初始化不成功。
使用双引号""
和单引号‘’
的字符或者字符串对于Groovy
都是String
类型的对象。
public static void main(String[] args) {
println "3".class.getName()
println '3'.class.getName()
}
控制台输出:
INFO-> 当前用户:fv,IP:10.60.131.54,工作目录:/Users/fv/Documents/workspace/fun/,系统编码格式:UTF-8,系统Mac OS X版本:10.16
java.lang.String
java.lang.String
Process finished with exit code 0
改正
所以在写枚举类对象的时候,需要特殊处理一下字符或者字符串,正确的使用方法如下:
class MocoDemo extends MocoServer {
public static void main(String[] args) {
println FunTester.FUN
}
static enum FunTester {
FUN((char)'3'),TESTER((char)'2')
char name
FunTester(char name) {
this.name = name
}
}
}
控制台输出
INFO-> 当前用户:fv,IP:10.60.131.54,工作目录:/Users/fv/Documents/workspace/fun/,系统编码格式:UTF-8,系统Mac OS X版本:10.16
FUN
Process finished with exit code 0
FunTester,非著名测试开发,文章记录学习和感悟,欢迎关注,交流成长。
FunTester 热文精选
TesterHome 为用户提供「保留所有权利,禁止转载」的选项。
除非获得原作者的单独授权,任何第三方不得转载标注了「原创声明:保留所有权利,禁止转载」的内容,否则均视为侵权。
具体请参见TesterHome 知识产权保护协议。
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
暂无回复。