何时抛出java.lang.EnumConstantNotPresentException?
根据java API,当应用程序尝试按名称访问枚举常量且枚举类型不包含具有指定名称的常量时,将引发EnumConstantNotPresentException 因此,我决定提出一个抛出java.lang.EnumConstantNotPresentException的场景,因此我编写了以下三个类 髓鞘类:何时抛出java.lang.EnumConstantNotPresentException?,java,enums,runtimeexception,Java,Enums,Runtimeexception,根据java API,当应用程序尝试按名称访问枚举常量且枚举类型不包含具有指定名称的常量时,将引发EnumConstantNotPresentException 因此,我决定提出一个抛出java.lang.EnumConstantNotPresentException的场景,因此我编写了以下三个类 髓鞘类: package my.enumtest; enum MyEnum { A, B, C; } MyEnumTest1类: package my.enumtest; imp
package my.enumtest;
enum MyEnum {
A, B, C;
}
MyEnumTest1类:
package my.enumtest;
import my.enumtest.MyEnum;
class MyEnumTest1 {
public static void main(String [] args) {
System.out.println(MyEnum.A);
}
}
MyEnumTest2类:
package my.enumtest;
import my.enumtest.MyEnum;
class MyEnumTest2 {
public static void main(String [] args) {
System.out.println(MyEnum.valueOf("A"));
}
}
我编译了所有三个,然后将MyEnum类更改为删除常量“A”,并重新编译:
package my.enumtest;
enum MyEnum {
B, C;
}
在使用新的MyEnum类执行MyEnumTest1时,我遇到以下异常:
线程“main”中出现异常
java.lang.NoSuchFieldError:A
在my.enumtest.MyEnumTest1.main(MyEnumTest1.java:8)中
在使用新的MyEnum类执行MyEnumTest2时,我遇到以下异常:
线程“main”java.lang.IllegalArgumentException中的异常:无枚举
常量my.enumtest.MyEnum.A
位于java.lang.Enum.valueOf(未知源)
在my.enumtest.MyEnum.valueOf(MyEnum.java:3)中
在my.enumtest.MyEnumTest2.main(MyEnumTest2.java:8)中
正如您所看到的,在我没有得到EnumConstantNotPresentException的情况下,有人能为我提供EnumConstantNotPresentException类的用法吗
p.S.我知道这个异常可以由用于反射式读取注释的引发,但我正在寻找更明显(更简单)的场景。如果您想知道何时引发特定异常,首先应该做的事情是按照JB Nizet提到的内容进行阅读。它说: 当应用程序尝试按名称访问枚举常量且枚举类型不包含具有指定名称的常量时引发。此异常可以由引发 以下链接指向
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());
}
}
编译所有内容并运行ReadAnnotation
。您将获得C
现在从TestEnum
中删除C
,只重新编译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)
如果您想知道它是否可以被其他任何东西抛出,您可以在JDK源代码中扫描这个异常名称。我没有发现任何其他提到这个异常的地方,所以反射似乎是唯一可能的情况。java中的枚举通常也称为合成糖这是什么意思? 枚举常量在编译时转换为公共静态final MyEnum字段,其中包含枚举常量的名称和类的构造函数的值。 这意味着通过访问MyEnum.MY_常量,您可以访问字段:
public static final MyEnum MY_CONSTANT = new MyEnum();
由于反射API现在还提供了通过getEnumConstants()
和isEnumConstant()
检查枚举常量的方法(请参阅指南中的Enaming Enums),因此java有一种方法来判断哪个字段是枚举常量,哪个字段不是。所以这些字段并不像你在第一段之后想的那么简单
引发NoSuchFieldException是因为。。。嗯,没有相应的枚举创建这样的字段
IllegalArgumentException由反射API引发,因为它是为该API设计的异常,例如
Enum\valueOf()
。该方法使用反射按名称(字符串)查找给定的枚举常量。这是指向EnumConstantNotPresentException类的链接。javadoc()的问题是,我感觉自己遗漏了什么:*这个异常可以由用于反射式读取注释的API引发。*,并包含一个指向类的链接,该类描述了何时引发异常。这是一个很好的示例,但我认为如果您包含一个解释,说明为什么会触发EnumConstantNotPresentException
,以及为什么sactiw的示例不触发异常,那么这将是一个更好的答案。@Tagir+1作为您的回答,但在我的问题中,我已经有了一个脚注提到它们可以由用于反射性地读取注释的脚本抛出,但我正在寻找更明显(更简单)的场景。基本上,它们可以在任何其他场景中抛出吗?@sactiw,检查我回答最后的注释。@Tagir是的,我理解你的观点,我已经这样做了,没有遇到任何用法。但是API并没有说“这个异常只能由用于反射式读取注释的API引发”,对吗?@sactiw,这样的评论会限制JDK开发人员进一步扩展这个异常的使用。因此,目前它仅用于反射,但开发人员将来可以自由添加更多的使用模式。不确定您是否仔细阅读了该问题,因为示例中的第3个类使用了valueOf()方法,并如预期的那样抛出java.lang.IllegalArgumentException:No enum constant
和not EnumConstantNotPresentException。我的回答只是解释了有关枚举的一些差异,并没有回答您的问题。