Enum在Groovy 2.x中导致ExceptionInInitializerError

时间:2014-11-29 19:46:13

标签: exception groovy static enums

我的枚举:

enum ServiceEnvironment implements ServiceEnvironmentStatics {
    Local(LOCAL_URI),
    Sandbox(SANDBOX_URI),
    Production(PRODUCTION_URI)

    private final String uri

    private ServiceEnvironment(String uri) {
        super()

        this.uri = uri
    }
}

interface ServiceEnvironmentStatics {
    static final String LOCAL_URI = "localhost:8080"
    static final String SANDBOX_URI = "sandbox.myapi.example.com"
    static final String PRODUCTION_URI = "myapi.example.com"
}

当我在代码中使用它时:

ServiceEnvironment env = ServiceEnvironment.Local

我明白了:

Caused by: groovy.lang.GroovyRuntimeException: Could not find matching constructor for: com.me.myapp.ServiceEnvironment(java.lang.String, java.lang.Integer, java.lang.String)
    at groovy.lang.MetaClassImpl.selectConstructorAndTransformArguments1(MetaClassImpl.java:1490)
    at groovy.lang.MetaClassImpl.selectConstructorAndTransformArguments(MetaClassImpl.java:1409)
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.selectConstructorAndTransformArguments(ScriptBytecodeAdapter.java:234)
    at com.me.myapp.ServiceEnvironment.$INIT(ServiceEnvironment.groovy)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
    at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite.invoke(StaticMetaMethodSite.java:43)
    at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite.callStatic(StaticMetaMethodSite.java:99)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:53)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:157)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:173)
    at com.me.myapp.ServiceEnvironment.<clinit>(ServiceEnvironment.groovy)
    ... 36 more

发生了什么?

1 个答案:

答案 0 :(得分:3)

tl; dr:super()构造函数中删除enum次调用。

实际答案:所有enum类的唯一超类是java.lang.Enum,它没有无参数构造函数。因此,行super()出错了。由于Groovy中动态方法/构造函数调度的性质,此处的运行时错误相当误导。如果我们试图在Java中编译一个大致相当的enum类:

public enum ServiceEnvironment {
    Local("localhost:8080"),
    Sandbox("sandbox.myapi.example.com"),
    Production("myapi.example.com");

    private final String uri;

    private ServiceEnvironment(String uri) {
        super();
        this.uri = uri;
    }
}

编译器会直接告诉我们super()语句是问题所在。我的Java编译器说:

Cannot invoke super constructor from enum constructor ServiceEnvironment(String)

...这在编译时比Groovy在运行时提供的消息更有意义。