--- a/src/java.base/share/classes/java/lang/Enum.java Sat Dec 08 18:52:57 2018 -0500
+++ b/src/java.base/share/classes/java/lang/Enum.java Sun Dec 09 12:36:24 2018 -0500
@@ -25,11 +25,19 @@
package java.lang;
-import java.io.Serializable;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.lang.constant.ClassDesc;
+import java.lang.constant.Constable;
+import java.lang.constant.ConstantDescs;
+import java.lang.constant.DynamicConstantDesc;
+import java.lang.invoke.MethodHandles;
+import java.util.Optional;
+
+import static java.util.Objects.requireNonNull;
/**
* This is the common base class of all Java language enumeration types.
@@ -56,7 +64,7 @@
@SuppressWarnings("serial") // No serialVersionUID needed due to
// special-casing of enum types.
public abstract class Enum<E extends Enum<E>>
- implements Comparable<E>, Serializable {
+ implements Constable, Comparable<E>, Serializable {
/**
* The name of this enum constant, as declared in the enum declaration.
* Most programmers should use the {@link #toString} method rather than
@@ -204,6 +212,21 @@
}
/**
+ * Returns an enum descriptor {@code EnumDesc} for this instance, if one can be
+ * constructed, or an empty {@link Optional} if one cannot be.
+ *
+ * @return An {@link Optional} containing the resulting nominal descriptor,
+ * or an empty {@link Optional} if one cannot be constructed.
+ * @since 12
+ */
+ @Override
+ public final Optional<EnumDesc<E>> describeConstable() {
+ return getDeclaringClass()
+ .describeConstable()
+ .map(c -> EnumDesc.of(c, name));
+ }
+
+ /**
* Returns the enum constant of the specified enum type with the
* specified name. The name must match exactly an identifier used
* to declare an enum constant in this type. (Extraneous whitespace
@@ -258,4 +281,56 @@
private void readObjectNoData() throws ObjectStreamException {
throw new InvalidObjectException("can't deserialize enum");
}
+
+ /**
+ * A <a href="package-summary.html#nominal">nominal descriptor</a> for an
+ * {@code enum} constant.
+ *
+ * @param <E> the type of the enum constant
+ *
+ * @since 12
+ */
+ public static final class EnumDesc<E extends Enum<E>>
+ extends DynamicConstantDesc<E> {
+
+ /**
+ * Constructs a nominal descriptor for the specified {@code enum} class and name.
+ *
+ * @param constantType a {@link ClassDesc} describing the {@code enum} class
+ * @param constantName the unqualified name of the enum constant
+ * @throws NullPointerException if any argument is null
+ * @jvms 4.2.2 Unqualified Names
+ */
+ private EnumDesc(ClassDesc constantType, String constantName) {
+ super(ConstantDescs.BSM_ENUM_CONSTANT, requireNonNull(constantName), requireNonNull(constantType));
+ }
+
+ /**
+ * Returns a nominal descriptor for the specified {@code enum} class and name
+ *
+ * @param <E> the type of the enum constant
+ * @param enumClass a {@link ClassDesc} describing the {@code enum} class
+ * @param constantName the unqualified name of the enum constant
+ * @return the nominal descriptor
+ * @throws NullPointerException if any argument is null
+ * @jvms 4.2.2 Unqualified Names
+ * @since 12
+ */
+ public static<E extends Enum<E>> EnumDesc<E> of(ClassDesc enumClass,
+ String constantName) {
+ return new EnumDesc<>(enumClass, constantName);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public E resolveConstantDesc(MethodHandles.Lookup lookup)
+ throws ReflectiveOperationException {
+ return Enum.valueOf((Class<E>) constantType().resolveConstantDesc(lookup), constantName());
+ }
+
+ @Override
+ public String toString() {
+ return String.format("EnumDesc[%s.%s]", constantType().displayName(), constantName());
+ }
+ }
}