什么时候抛出 java.lang.EnumConstantNotPresentException ?

sac*_*tiw 5 java enums runtimeexception

根据 java API,当应用程序尝试按名称访问枚举常量并且枚举类型不包含具有指定名称的常量时,会引发 EnumConstantNotPresentException。

因此我决定提出一个抛出 java.lang.EnumConstantNotPresentException 的场景,所以我编写了以下三个类。

我的枚举类:

package my.enumtest;

enum MyEnum {
    A, B, C;
}
Run Code Online (Sandbox Code Playgroud)

MyEnumTest1 类:

package my.enumtest;

    import my.enumtest.MyEnum;

    class MyEnumTest1 {

        public static void main(String [] args) {
            System.out.println(MyEnum.A);        
        }        
    }
Run Code Online (Sandbox Code Playgroud)

MyEnumTest2 类:

package my.enumtest;

import my.enumtest.MyEnum;

class MyEnumTest2 {

    public static void main(String [] args) {
        System.out.println(MyEnum.valueOf("A"));        
    }
}
Run Code Online (Sandbox Code Playgroud)

我编译了所有三个,然后更改了 MyEnum 类以删除常量“A”并重新编译它:

package my.enumtest;

enum MyEnum {
    B, C;
}
Run Code Online (Sandbox Code Playgroud)

在使用新的 MyEnum 类执行 MyEnumTest1 时,出现以下异常:

线程“main”中的异常 java.lang.NoSuchFieldError: A at my.enumtest.MyEnumTest1.main(MyEnumTest1.java:8)

在使用新的 MyEnum 类执行 MyEnumTest2 时,出现以下异常:

线程“main”中的异常 java.lang.IllegalArgumentException:在 my.enumtest.MyEnum.valueOf(MyEnum.java:3) 处的 java.lang.Enum.valueOf(未知来源) 处没有枚举常量 my.enumtest.MyEnum.A my.enumtest.MyEnumTest2.main(MyEnumTest2.java:8)

正如您所看到的,在所有情况下我都没有遇到 EnumConstantNotPresentException,那么有人可以向我提供 EnumConstantNotPresentException 类的用法吗?

PS我知道用于反射式读取注释的API可能会引发此异常,但我正在寻找更明显(更简单)的场景。

Tag*_*eev 3

如果您想知道何时引发特定异常,您应该做的第一件事是阅读JB Nizet 提到的文档。它说:

当应用程序尝试按名称访问枚举常量并且枚举类型不包含具有指定名称的常量时抛出。用于反射式读取注释的 API可能会引发此异常。

链接如下,AnnotationElement文档显示:

EnumConstantNotPresentException同样,如果注释中的枚举常量不再存在于枚举类型中,则尝试读取枚举值成员将导致。

这足以制作一个例子。创建以下类:

// TestEnum.java
public enum TestEnum {
    A, B, C;
}

// TestAnnotation.java
import java.lang.annotation.*;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
    TestEnum value();
}

// TestClass.java
@TestAnnotation(TestEnum.C)
public class TestClass {

}

// ReadAnnotation.java
public class ReadAnnotation {
    public static void main(String[] args) {
        System.out.println(TestClass.class.getAnnotation(TestAnnotation.class).value());
    }
}
Run Code Online (Sandbox Code Playgroud)

编译所有内容并运行ReadAnnotation。你会得到C

C现在从 中删除TestEnum并仅重新编译TestEnum类,按原样保留其他类。如果您ReadAnnotation现在启动,您将获得:

Exception in thread "main" java.lang.EnumConstantNotPresentException: TestEnum.C
    at sun.reflect.annotation.EnumConstantNotPresentExceptionProxy.generateException(Unknown Source)
    at sun.reflect.annotation.AnnotationInvocationHandler.invoke(Unknown Source)
    at com.sun.proxy.$Proxy1.value(Unknown Source)
    at ReadAnnotation.main(ReadAnnotation.java:4)
Run Code Online (Sandbox Code Playgroud)

如果您想知道它是否可以由其他任何东西引发,您可以扫描 JDK 源以查找此异常名称。我没有发现任何其他提及此异常的情况,因此反射似乎是唯一可能的情况。

  • 这是一个很好的例子,但我认为如果您解释为什么会触发“EnumConstantNotPresentException”以及为什么 sactiw 的示例不会触发“EnumConstantNotPresentException”,那么这将是一个更好的答案。 (2认同)