When is java.lang.EnumConstantNotPresentException thrown?

According to the java API, EnumConstantNotPresentException gets thrown when an application tries to access an enum constant by name and the enum type does not contain a constant with the specified name.

So I decided to come up with a scenario that throws java.lang.EnumConstantNotPresentException, so I wrote the following three classes.

MyEnum class:

package my.enumtest;

enum MyEnum {
    A, B, C;
}

      

MyEnumTest1 class:

package my.enumtest;

    import my.enumtest.MyEnum;

    class MyEnumTest1 {

        public static void main(String [] args) {
            System.out.println(MyEnum.A);        
        }        
    }

      

MyEnumTest2 class:

package my.enumtest;

import my.enumtest.MyEnum;

class MyEnumTest2 {

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

      

I compiled all three, and then I modified the MyEnum class to remove the constant "A" and recompile it:

package my.enumtest;

enum MyEnum {
    B, C;
}

      

When executing MyEnumTest1 with the new class MyEnum, I got the following exception:

Exception on thread "main" java.lang.NoSuchFieldError: A at my.enumtest.MyEnumTest1.main (MyEnumTest1.java:8)

When running MyEnumTest2 with the new class MyEnum, I got the following exception:

Exception on thread "main" java.lang.IllegalArgumentException: No enumeration persistent my.enumtest.MyEnum.A. at java.lang.Enum.valueOf (Unknown source) at my.enumtest.MyEnum.valueOf (MyEnum.java:3) at my.enumtest.MyEnumTest2.main (MyEnumTest2.java:8)

As you can see in none of the cases I got an EnumConstantNotPresentException, so can anyone please provide me with a use of the EnumConstantNotPresentException class?

PS I know this exception can be thrown by the API used to read comments, but I'm looking for a more obvious (simpler) scenario.

+3


source to share


2 answers


The first thing you need to do if you want to know when a particular exception is thrown is to read the documentation that JB Nizet mentioned. It says:

Thrown when an application tries to access an enumeration constant by name and the enumeration type does not contain a constant with the specified name. This exception can be thrown by the API used for annotation reflection .

The link matches AnnotationElement

, in the documentation:

Likewise, attempting to read an element with an enumeration will result in EnumConstantNotPresentException

if the enumeration constant in the annotation is no longer present in the enumeration type.

This is enough to create an example. Create the following classes:



// 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());
    }
}

      

Compile everything and run ReadAnnotation

. You will receive C

.

Now remove C

from TestEnum

and recompile just the class TestEnum

, keeping the other classes as they are. If you run ReadAnnotation

now, you get:

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)

      

If you are wondering if it might be thrown by anyone else, you can scan JDK sources for that exception name. I haven't found any other mention of this exception, so it seems like reflection is the only possible case.

+2


source


Enum in java is often also called synthetic sugar. What is meant by this?

Enum constants are converted to public static final fields MyEnum with the enum constant name and class constructor value at compile time. This means that when you access MyEnum.MY_CONSTANT, you access the field:

public static final MyEnum MY_CONSTANT = new MyEnum();

      



Since the reflection API now also provides methods for validating enum constants (see Enamiming Enums in the Manual) via getEnumConstants()

and isEnumConstant()

, java has a way to determine which field was an enum constant and which field was not.Thus , these fields are not that simple as you think after the first paragraph.

The NoSuchFieldException is thrown because ... well, there is no such field created by the corresponding enumeration.

The IllegalArgumentException is thrown by the reflection API, as it is an exception designed for that API and for example Enum#valueOf()

. This method uses reflection to find the given enum constant by name (string).

0


source







All Articles