char *初始化_Groovy枚举类初始化异常分析

之前写过一些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 nameFunTester(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.(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里面对于双引号""和单引号‘’是不区分charString的,应该是这个原因导致枚举类初始化不成功。

使用双引号""和单引号‘’的字符或者字符串对于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 nameFunTester(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热文精选

  • 避免PPT自动化的最佳实践
  • 固定QPS压测初试
  • API自动化测试指南
  • 如何测试概率型业务接口
  • “双花”BUG的测试分享
  • Socket.IO接口多用户测试实践
  • 链路压测中如何记录每一个耗时的请求
  • JSON对象标记语法验证类
  • Gradle+Groovy基础篇
  • Gradle+Groovy提高篇
b9a26c80d25de3ee04bedb70e86ba6a1.png
点击阅读原文,查看公众号历史文章
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值