Examining Enums
Class.isEnum() Indicates whether this class represents an enum type Class.getEnumConstants() Retrieves the list of enum constants defined by the enum in the order they’re declared java.lang.reflect.Field.isEnumConstant() Indicates whether this field represents an element of an enumerated type
Sometimes it is necessary to dynamically retrieve the list of enum constants; in non-reflective code this is accomplished by invoking the implicitly declared static method values() on the enum. If an instance of an enum type is not available the only way to get a list of the possible values is to invoke Class.getEnumConstants() since it is impossible to instantiate an enum type.
Given a fully qualified name, the EnumConstants example shows how to retrieve an ordered list of constants in an enum using Class.getEnumConstants() .
import java.util.Arrays; import static java.lang.System.out; enum Eon < HADEAN, ARCHAEAN, PROTEROZOIC, PHANEROZOIC >public class EnumConstants < public static void main(String. args) < try < Classc = (args.length == 0 ? Eon.class : Class.forName(args[0])); out.format("Enum name: %s%nEnum constants: %s%n", c.getName(), Arrays.asList(c.getEnumConstants())); if (c == Eon.class) out.format(" Eon.values(): %s%n", Arrays.asList(Eon.values())); // production code should handle this exception more gracefully > catch (ClassNotFoundException x) < x.printStackTrace(); >> >
Samples of the output follows. User input is in italics.
$ java EnumConstants java.lang.annotation.RetentionPolicy Enum name: java.lang.annotation.RetentionPolicy Enum constants: [SOURCE, CLASS, RUNTIME]
$ java EnumConstants java.util.concurrent.TimeUnit Enum name: java.util.concurrent.TimeUnit Enum constants: [NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS]
This example also shows that value returned by Class.getEnumConstants() is identical to the value returned by invoking values() on an enum type.
$ java EnumConstants Enum name: Eon Enum constants: [HADEAN, ARCHAEAN, PROTEROZOIC, PHANEROZOIC] Eon.values(): [HADEAN, ARCHAEAN, PROTEROZOIC, PHANEROZOIC]
Since enums are classes, other information may be obtained using the same Reflection APIs described in the Fields, Methods, and Constructors sections of this trail. The EnumSpy code illustrates how to use these APIs to get additional information about the enum’s declaration. The example uses Class.isEnum() to restrict the set of classes examined. It also uses Field.isEnumConstant() to distinguish enum constants from other fields in the enum declaration (not all fields are enum constants).
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Member; import java.util.List; import java.util.ArrayList; import static java.lang.System.out; public class EnumSpy < private static final String fmt = " %11s: %s %s%n"; public static void main(String. args) < try < Classc = Class.forName(args[0]); if (!c.isEnum()) < out.format("%s is not an enum type%n", c); return; >out.format("Class: %s%n", c); Field[] flds = c.getDeclaredFields(); List cst = new ArrayList(); // enum constants List mbr = new ArrayList(); // member fields for (Field f : flds) < if (f.isEnumConstant()) cst.add(f); else mbr.add(f); >if (!cst.isEmpty()) print(cst, "Constant"); if (!mbr.isEmpty()) print(mbr, "Field"); Constructor[] ctors = c.getDeclaredConstructors(); for (Constructor ctor : ctors) < out.format(fmt, "Constructor", ctor.toGenericString(), synthetic(ctor)); >Method[] mths = c.getDeclaredMethods(); for (Method m : mths) < out.format(fmt, "Method", m.toGenericString(), synthetic(m)); >// production code should handle this exception more gracefully > catch (ClassNotFoundException x) < x.printStackTrace(); >> private static void print(List lst, String s) < for (Field f : lst) < out.format(fmt, s, f.toGenericString(), synthetic(f)); >> private static String synthetic(Member m) < return (m.isSynthetic() ? "[ synthetic ]" : ""); >>
$ java EnumSpy java.lang.annotation.RetentionPolicy Class: class java.lang.annotation.RetentionPolicy Constant: public static final java.lang.annotation.RetentionPolicy java.lang.annotation.RetentionPolicy.SOURCE Constant: public static final java.lang.annotation.RetentionPolicy java.lang.annotation.RetentionPolicy.CLASS Constant: public static final java.lang.annotation.RetentionPolicy java.lang.annotation.RetentionPolicy.RUNTIME Field: private static final java.lang.annotation.RetentionPolicy[] java.lang.annotation.RetentionPolicy. [ synthetic ] Constructor: private java.lang.annotation.RetentionPolicy() Method: public static java.lang.annotation.RetentionPolicy[] java.lang.annotation.RetentionPolicy.values() Method: public static java.lang.annotation.RetentionPolicy java.lang.annotation.RetentionPolicy.valueOf(java.lang.String)
The output shows that declaration of java.lang.annotation.RetentionPolicy only contains the three enum constants. The enum constants are exposed as public static final fields. The field, constructor, and methods are compiler generated. The $VALUES field is related to the implementation of the values() method.
Note: For various reasons, including support for evolution of the enum type, the declaration order of enum constants is important. Class.getFields() and Class.getDeclaredFields() do not make any guarantee that the order of the returned values matches the order in the declaring source code. If ordering is required by an application, use Class.getEnumConstants() .
The output for java.util.concurrent.TimeUnit shows that much more complicated enums are possible. This class includes several methods as well as additional fields declared static final which are not enum constants.
$ java EnumSpy java.util.concurrent.TimeUnit Class: class java.util.concurrent.TimeUnit Constant: public static final java.util.concurrent.TimeUnit java.util.concurrent.TimeUnit.NANOSECONDS Constant: public static final java.util.concurrent.TimeUnit java.util.concurrent.TimeUnit.MICROSECONDS Constant: public static final java.util.concurrent.TimeUnit java.util.concurrent.TimeUnit.MILLISECONDS Constant: public static final java.util.concurrent.TimeUnit java.util.concurrent.TimeUnit.SECONDS Constant: public static final java.util.concurrent.TimeUnit java.util.concurrent.TimeUnit.MINUTES Constant: public static final java.util.concurrent.TimeUnit java.util.concurrent.TimeUnit.HOURS Constant: public static final java.util.concurrent.TimeUnit java.util.concurrent.TimeUnit.DAYS Field: static final long java.util.concurrent.TimeUnit.C0 Field: static final long java.util.concurrent.TimeUnit.C1 Field: static final long java.util.concurrent.TimeUnit.C2 Field: static final long java.util.concurrent.TimeUnit.C3 Field: static final long java.util.concurrent.TimeUnit.C4 Field: static final long java.util.concurrent.TimeUnit.C5 Field: static final long java.util.concurrent.TimeUnit.C6 Field: static final long java.util.concurrent.TimeUnit.MAX Field: private static final java.util.concurrent.TimeUnit[] java.util.concurrent.TimeUnit. [ synthetic ] Constructor: private java.util.concurrent.TimeUnit() Constructor: java.util.concurrent.TimeUnit (java.lang.String,int,java.util.concurrent.TimeUnit) [ synthetic ] Method: public static java.util.concurrent.TimeUnit java.util.concurrent.TimeUnit.valueOf(java.lang.String) Method: public static java.util.concurrent.TimeUnit[] java.util.concurrent.TimeUnit.values() Method: public void java.util.concurrent.TimeUnit.sleep(long) throws java.lang.InterruptedException Method: public long java.util.concurrent.TimeUnit.toNanos(long) Method: public long java.util.concurrent.TimeUnit.convert (long,java.util.concurrent.TimeUnit) Method: abstract int java.util.concurrent.TimeUnit.excessNanos (long,long) Method: public void java.util.concurrent.TimeUnit.timedJoin (java.lang.Thread,long) throws java.lang.InterruptedException Method: public void java.util.concurrent.TimeUnit.timedWait (java.lang.Object,long) throws java.lang.InterruptedException Method: public long java.util.concurrent.TimeUnit.toDays(long) Method: public long java.util.concurrent.TimeUnit.toHours(long) Method: public long java.util.concurrent.TimeUnit.toMicros(long) Method: public long java.util.concurrent.TimeUnit.toMillis(long) Method: public long java.util.concurrent.TimeUnit.toMinutes(long) Method: public long java.util.concurrent.TimeUnit.toSeconds(long) Method: static long java.util.concurrent.TimeUnit.x(long,long,long)
How to javadoc a class’s individual enums?
Javadoc is a powerful tool that helps developers to generate API documentation from the Java code. One common challenge when documenting a Java class is how to include information about the individual enums within the class. The Javadoc tool does not provide direct support for documenting individual enums, which can make it difficult to understand the purpose and usage of each enum. In this article, we’ll look at a few methods for documenting individual enums in Java, so that your code is easy to understand and maintain for others.
Method 1: Use Enum Constants’ Javadoc
To Javadoc a class’s individual enums in Java, you can use the «Use Enum Constants’ Javadoc» approach. This involves adding Javadoc comments directly above each enum constant in the enum definition.
Here’s an example enum definition with Javadoc comments for each constant:
/** * This enum represents the different types of fruits. */ public enum FruitType /** * Represents an apple. */ APPLE, /** * Represents a banana. */ BANANA, /** * Represents an orange. */ ORANGE >
In the example above, we have added Javadoc comments for each enum constant. These comments describe what each constant represents.
To access the Javadoc comments for an enum constant, you can use the @see tag in your own Javadoc comments. For example:
/** * This class represents a fruit. * * @see FruitType#APPLE * @see FruitType#BANANA * @see FruitType#ORANGE */ public class Fruit // . >
In the example above, we have used the @see tag to reference the Javadoc comments for each enum constant in the FruitType enum.
By using the «Use Enum Constants’ Javadoc» approach, you can easily add Javadoc comments for each enum constant in your Java code. This can help improve the readability and maintainability of your code, especially if you are working with large enum definitions.
Method 2: Use a Separate Enum Class
To Javadoc a class’s individual enums in Java using a separate enum class, follow these steps:
/** * This is a separate enum class for the main class. */ public enum MainClassEnum /** * This is the first enum value. */ FIRST_ENUM_VALUE, /** * This is the second enum value. */ SECOND_ENUM_VALUE >
/** * This is the main class that uses the separate enum class. */ public class MainClass /** * This method uses the separate enum class. * @param enumValue the enum value to use */ public void useEnum(MainClassEnum enumValue) // code to use the enum value > >
/** * This is a separate enum class for the main class. */ public enum MainClassEnum /** * This is the first enum value. * @return a string representation of the enum value */ FIRST_ENUM_VALUE @Override public String toString() return "First Enum Value"; > >, /** * This is the second enum value. * @return a string representation of the enum value */ SECOND_ENUM_VALUE @Override public String toString() return "Second Enum Value"; > > >
/** * This is the main class that uses the separate enum class. */ public class MainClass /** * This method uses the separate enum class. * @param enumValue the enum value to use * @see MainClassEnum */ public void useEnum(MainClassEnum enumValue) // code to use the enum value > >
That’s it! You can now Javadoc a class’s individual enums in Java using a separate enum class.
Method 3: Use Enum Annotation
To Javadoc a Class’s Individual Enums in Java, you can use the Enum Annotation. Here’s how to do it:
/** * Represents the different types of fruits. */ public enum FruitType /** * Represents an apple fruit. */ @EnumDescription("A round fruit with a red, green, or yellow skin.") APPLE, /** * Represents a banana fruit. */ @EnumDescription("A long, curved fruit with a yellow skin.") BANANA, /** * Represents an orange fruit. */ @EnumDescription("A round fruit with an orange skin.") ORANGE >
/** * Annotation to describe an enum value. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface EnumDescription /** * Returns the description of the enum value. * * @return the description of the enum value */ String value(); >
/** * Returns the description of the given fruit type. * * @param fruitType the fruit type to describe * @return the description of the given fruit type * @throws IllegalArgumentException if the given fruit type is null * @see FruitType * @see FruitType#APPLE * @see FruitType#BANANA * @see FruitType#ORANGE * @see EnumDescription * @see FruitType#APPLE * @see FruitType#BANANA * @see FruitType#ORANGE */ public String describeFruitType(FruitType fruitType) if (fruitType == null) throw new IllegalArgumentException("Fruit type cannot be null"); > try Field field = FruitType.class.getField(fruitType.name()); EnumDescription description = field.getAnnotation(EnumDescription.class); return description.value(); > catch (NoSuchFieldException ex) throw new IllegalArgumentException("Invalid fruit type: " + fruitType.name(), ex); > >
With these steps, you can Javadoc a Class’s Individual Enums using the Enum Annotation in Java.