JDK-8336353 : Revisit AnnotationConstantValueEntry and AnnotationValue.OfConstant
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.lang.classfile
  • Priority: P4
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 24
  • Submitted: 2024-07-14
  • Updated: 2024-08-13
  • Resolved: 2024-08-13
Related Reports
CSR :  
Relates :  
Description
Summary
-------

Update specifications in `AnnotationConstantValueEntry` and `AnnotationValue.OfConstant`, and rename `AnnotationValue.OfInteger` and `OfCharacter` to `AnnotationValue.OfInt` and `AnnotationValue.OfChar`.

Problem
-------

`AnnotationConstantValueEntry` and `AnnotationValue.OfConstant` are old modeling APIs before [specific types of annotation values are added](https://github.com/openjdk/jdk-sandbox/commit/bb7e29474ecfcfbd1eb01d237593eb80d062944f). Their designs do not account for their presence.

`AnnotationValue.OfConstant` is bug-prone: for example, `ConstantDesc constantValue()` method returns an `Integer` for char values, which is misleading because users may think that it returns a correct `Character` Object suitable for `AnnotationValue::of` to restore the annotation value, or for `toString` printing. This is already manifest in ClassFile API's `ClassPrinter`.

`AnnotationValue.OfInteger` and `OfCharacter` have weird naming; their factories are `ofInt` and `ofChar`, tag constants `AEV_INT` and `AEV_CHAR`, value accessors `intValue` and `charValue`.

`AnnotationValue` as a whole lacks documentation and would benefit from the addition of documentation.

Solution
--------

Update AnnotationValue.OfConstant and AnnotationConstantValueEntry specifications, to emphasize the difference between VM types and the language types (namely subint are represented as int). `OfConstant` additionally has accessors for the VM (as CP entries) vs language types (as live objects), with clarifications on the methods.

`ConstantPoolBuilder::annotationConstantValueEntry` is removed. It had no usage.

The `AnnotationConstantValueEntry constant()` is now specific to each value subtype. Users are supposed to access the entry with pattern matching in switch.

`AnnotationValue.OfInteger` and `OfCharacter` are renamed to `OfInt` and `OfChar`.

Vastly improve the specification for AnnotationValue.

Specification
-------------
    --- a/src/java.base/share/classes/java/lang/classfile/AnnotationValue.java
    +++ b/src/java.base/share/classes/java/lang/classfile/AnnotationValue.java
     @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
    -public sealed interface AnnotationValue
    -        permits AnnotationValue.OfAnnotation, AnnotationValue.OfArray,
    -                AnnotationValue.OfConstant, AnnotationValue.OfClass,
    -                AnnotationValue.OfEnum {
    +public sealed interface AnnotationValue {
     
         /**
    -     * Models an annotation-valued element
    +     * Models an annotation-valued element.
    +     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_ANNOTATION}.
          *
          * @since 22
          */
         @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
         sealed interface OfAnnotation extends AnnotationValue
                 permits AnnotationImpl.OfAnnotationImpl {
    -        /** {@return the annotation} */
    +        /** {@return the annotation value} */
             Annotation annotation();
         }
     
         /**
    -     * Models an array-valued element
    +     * Models an array-valued element.
    +     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_ARRAY}.
          *
          * @since 22
          */
         @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
         sealed interface OfArray extends AnnotationValue
                 permits AnnotationImpl.OfArrayImpl {
    -        /** {@return the values} */
    +        /**
    +         * {@return the array elements of the array value}
    +         *
    +         * @apiNote
    +         * All array elements derived from Java source code have the same type,
    +         * which must not be an array type. ({@jls 9.6.1})
    +         */
             List<AnnotationValue> values();
         }
     
         /**
    -     * Models a constant-valued element
    +     * Models a constant-valued element.
          *
          * @sealedGraph
          * @since 22
          */
         @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
    -    sealed interface OfConstant extends AnnotationValue
    -            permits AnnotationValue.OfString, AnnotationValue.OfDouble,
    -                    AnnotationValue.OfFloat, AnnotationValue.OfLong,
    -                    AnnotationValue.OfInteger, AnnotationValue.OfShort,
    -                    AnnotationValue.OfCharacter, AnnotationValue.OfByte,
    -                    AnnotationValue.OfBoolean, AnnotationImpl.OfConstantImpl {
    -        /** {@return the constant} */
    -        /** {@return the constant} */
    -        ConstantDesc constantValue();
    -    }
    -
    -    /**
    -     * Models a constant-valued element
    +    sealed interface OfConstant
    +            extends AnnotationValue
    +            permits OfString, OfDouble, OfFloat, OfLong, OfInt, OfShort, OfChar, OfByte,
    +                    OfBoolean, AnnotationImpl.OfConstantImpl {
    +        /**
    +         * {@return the constant pool entry backing this constant element}
    +         *
    +         * @apiNote
    +         * Different types of constant values may share the same type of entry.
    +         * For example, {@link OfInt} and {@link OfChar} are both
    +         * backed by {@link IntegerEntry}. Use {@link #resolvedValue
    +         * resolvedValue()} for a value of accurate type.
    +         */
             AnnotationConstantValueEntry constant();
    +
    +        /**
    +         * {@return the resolved live constant value, as an object} The type of
    +         * the returned value may be a wrapper class or {@link String}.
    +         *
    +         * @apiNote
    +         * The returned object, despite being {@link Constable}, may not
    +         * {@linkplain Constable#describeConstable() describe} the right constant
    +         * for encoding the annotation value in a class file. For example,
    +         * {@link Character} returned by {@link OfChar} describes itself as a
    +         * {@link DynamicConstantPoolEntry}, but it is actually backed by
    +         * {@link IntegerEntry} in annotation format.
    +         * Use {@link #constant constant()} for a correct constant pool representation.
    +         */
    +        Constable resolvedValue();
    +    }
    +
    +    /**
    +     * Models a string-valued element.
    +     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_STRING}.
          *
          * @since 22
          */
         @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
    -    sealed interface OfString extends AnnotationValue.OfConstant
    +    sealed interface OfString extends OfConstant
                 permits AnnotationImpl.OfStringImpl {
    -        /** {@return the constant} */
    +        /** {@return the backing UTF8 entry} */
    +        @Override
    +        Utf8Entry constant();
    +
    +        /** {@return the constant string value} */
             String stringValue();
    +
    +        /**
    +         * {@return the resolved string value}
    +         *
    +         * @implSpec
    +         * This method returns the same as {@link #stringValue()}.
    +         */
    +        @Override
    +        default String resolvedValue() {
    +            return stringValue();
    +        }
         }
     
         /**
    -     * Models a constant-valued element
    +     * Models a double-valued element.
    +     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_DOUBLE}.
          *
          * @since 22
          */
         @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
    -    sealed interface OfDouble extends AnnotationValue.OfConstant
    +    sealed interface OfDouble extends OfConstant
                 permits AnnotationImpl.OfDoubleImpl {
    -        /** {@return the constant} */
    +        /** {@return the backing double entry} */
    +        @Override
    +        DoubleEntry constant();
    +
    +        /** {@return the constant double value} */
             double doubleValue();
    +
    +        /**
    +         * {@return the resolved double value}
    +         *
    +         * @implSpec
    +         * This method returns the same as {@link #doubleValue()}.
    +         */
    +        @Override
    +        default Double resolvedValue() {
    +            return doubleValue();
    +        }
         }
     
         /**
    -     * Models a constant-valued element
    +     * Models a float-valued element.
    +     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_FLOAT}.
          *
          * @since 22
          */
         @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
    -    sealed interface OfFloat extends AnnotationValue.OfConstant
    +    sealed interface OfFloat extends OfConstant
                 permits AnnotationImpl.OfFloatImpl {
    -        /** {@return the constant} */
    +        /** {@return the backing float entry} */
    +        @Override
    +        FloatEntry constant();
    +
    +        /** {@return the constant float value} */
             float floatValue();
    +
    +        /**
    +         * {@return the resolved float value}
    +         *
    +         * @implSpec
    +         * This method returns the same as {@link #floatValue()}.
    +         */
    +        @Override
    +        default Float resolvedValue() {
    +            return floatValue();
    +        }
         }
     
         /**
    -     * Models a constant-valued element
    +     * Models a long-valued element.
    +     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_LONG}.
          *
          * @since 22
          */
         @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
    -    sealed interface OfLong extends AnnotationValue.OfConstant
    +    sealed interface OfLong extends OfConstant
                 permits AnnotationImpl.OfLongImpl {
    -        /** {@return the constant} */
    +        /** {@return the backing long entry} */
    +        @Override
    +        LongEntry constant();
    +
    +        /** {@return the constant long value} */
             long longValue();
    +
    +        /**
    +         * {@return the resolved long value}
    +         *
    +         * @implSpec
    +         * This method returns the same as {@link #longValue()}.
    +         */
    +        @Override
    +        default Long resolvedValue() {
    +            return longValue();
    +        }
         }
     
         /**
    -     * Models a constant-valued element
    +     * Models an int-valued element.
    +     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_INT}.
          *
          * @since 22
          */
         @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
    -    sealed interface OfInteger extends AnnotationValue.OfConstant
    -            permits AnnotationImpl.OfIntegerImpl {
    -        /** {@return the constant} */
    +    sealed interface OfInt extends OfConstant
    +            permits AnnotationImpl.OfIntImpl {
    +        /** {@return the backing integer entry} */
    +        @Override
    +        IntegerEntry constant();
    +
    +        /** {@return the constant int value} */
             int intValue();
    +
    +        /**
    +         * {@return the resolved int value}
    +         *
    +         * @implSpec
    +         * This method returns the same as {@link #intValue()}.
    +         */
    +        @Override
    +        default Integer resolvedValue() {
    +            return intValue();
    +        }
         }
     
         /**
    -     * Models a constant-valued element
    +     * Models a short-valued element.
    +     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_SHORT}.
          *
          * @since 22
          */
         @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
    -    sealed interface OfShort extends AnnotationValue.OfConstant
    +    sealed interface OfShort extends OfConstant
                 permits AnnotationImpl.OfShortImpl {
    -        /** {@return the constant} */
    +        /** {@return the backing integer entry} */
    +        @Override
    +        IntegerEntry constant();
    +
    +        /**
    +         * {@return the constant short value}
    +         * @jvms 2.11.1 Types and the Java Virtual Machine
    +         */
             short shortValue();
    +
    +        /**
    +         * {@return the resolved short value}
    +         *
    +         * @implSpec
    +         * This method returns the same as {@link #shortValue()}.
    +         */
    +        @Override
    +        default Short resolvedValue() {
    +            return shortValue();
    +        }
         }
     
         /**
    -     * Models a constant-valued element
    +     * Models a char-valued element.
    +     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_CHAR}.
          *
          * @since 22
          */
         @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
    -    sealed interface OfCharacter extends AnnotationValue.OfConstant
    -            permits AnnotationImpl.OfCharacterImpl {
    -        /** {@return the constant} */
    +    sealed interface OfChar extends OfConstant
    +            permits AnnotationImpl.OfCharImpl {
    +        /** {@return the backing integer entry} */
    +        @Override
    +        IntegerEntry constant();
    +
    +        /**
    +         * {@return the constant char value}
    +         * @jvms 2.11.1 Types and the Java Virtual Machine
    +         */
             char charValue();
    +
    +        /**
    +         * {@return the resolved char value}
    +         *
    +         * @implSpec
    +         * This method returns the same as {@link #charValue()}.
    +         */
    +        @Override
    +        default Character resolvedValue() {
    +            return charValue();
    +        }
         }
     
         /**
    -     * Models a constant-valued element
    +     * Models a byte-valued element.
    +     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_BYTE}.
          *
          * @since 22
          */
         @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
    -    sealed interface OfByte extends AnnotationValue.OfConstant
    +    sealed interface OfByte extends OfConstant
                 permits AnnotationImpl.OfByteImpl {
    -        /** {@return the constant} */
    +        /** {@return the backing integer entry} */
    +        @Override
    +        IntegerEntry constant();
    +
    +        /**
    +         * {@return the constant byte value}
    +         * @jvms 2.11.1 Types and the Java Virtual Machine
    +         */
             byte byteValue();
    +
    +        /**
    +         * {@return the resolved byte value}
    +         *
    +         * @implSpec
    +         * This method returns the same as {@link #byteValue()}.
    +         */
    +        @Override
    +        default Byte resolvedValue() {
    +            return byteValue();
    +        }
         }
     
         /**
    -     * Models a constant-valued element
    +     * Models a boolean-valued element.
    +     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_BOOLEAN}.
          *
          * @since 22
          */
         @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
    -    sealed interface OfBoolean extends AnnotationValue.OfConstant
    +    sealed interface OfBoolean extends OfConstant
                 permits AnnotationImpl.OfBooleanImpl {
    -        /** {@return the constant} */
    +        /** {@return the backing integer entry} */
    +        @Override
    +        IntegerEntry constant();
    +
    +        /**
    +         * {@return the constant boolean value}
    +         * @jvms 2.3.4 The <i>boolean</i> Type
    +         */
             boolean booleanValue();
    +
    +        /**
    +         * {@return the resolved boolean value}
    +         *
    +         * @implSpec
    +         * This method returns the same as {@link #booleanValue()}.
    +         */
    +        @Override
    +        default Boolean resolvedValue() {
    +            return booleanValue();
    +        }
         }
     
         /**
    -     * Models a class-valued element
    +     * Models a class-valued element.
    +     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_CLASS}.
          *
          * @since 22
          */
         @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
         sealed interface OfClass extends AnnotationValue
                 permits AnnotationImpl.OfClassImpl {
    -        /** {@return the class name} */
    +        /** {@return the class descriptor string} */
             Utf8Entry className();
     
    -        /** {@return the class symbol} */
    +        /** {@return the class descriptor} */
             default ClassDesc classSymbol() {
                 return ClassDesc.ofDescriptor(className().stringValue());
             }
         }
     
         /**
    -     * Models an enum-valued element
    +     * Models an enum-valued element.
    +     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_ENUM}.
          *
          * @since 22
          */
         @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
         sealed interface OfEnum extends AnnotationValue
                 permits AnnotationImpl.OfEnumImpl {
    -        /** {@return the enum class name} */
    +        /** {@return the enum class descriptor string} */
             Utf8Entry className();
     
    -        /** {@return the enum class symbol} */
    +        /** {@return the enum class descriptor} */
             default ClassDesc classSymbol() {
                 return ClassDesc.ofDescriptor(className().stringValue());
             }
    @@ -249,7 +432,7 @@ default ClassDesc classSymbol() {
     
         /**
          * {@return an annotation element for a enum-valued element}
    -     * @param className the name of the enum class
    +     * @param className the descriptor string of the enum class
          * @param constantName the name of the enum constant
          */
         static OfEnum ofEnum(Utf8Entry className,
    @@ -259,7 +442,7 @@ static OfEnum ofEnum(Utf8Entry className,
     
         /**
          * {@return an annotation element for a enum-valued element}
    -     * @param className the name of the enum class
    +     * @param className the descriptor of the enum class
          * @param constantName the name of the enum constant
          */
         static OfEnum ofEnum(ClassDesc className, String constantName) {
    @@ -269,7 +452,7 @@ static OfEnum ofEnum(ClassDesc className, String constantName) {
     
         /**
          * {@return an annotation element for a class-valued element}
    -     * @param className the name of the enum class
    +     * @param className the descriptor string of the class
          */
         static OfClass ofClass(Utf8Entry className) {
             return new AnnotationImpl.OfClassImpl(className);
    @@ -277,7 +460,7 @@ static OfClass ofClass(Utf8Entry className) {
     
         /**
          * {@return an annotation element for a class-valued element}
    -     * @param className the name of the enum class
    +     * @param className the descriptor of the class
          */
         static OfClass ofClass(ClassDesc className) {
             return ofClass(TemporaryConstantPool.INSTANCE.utf8Entry(className.descriptorString()));
    @@ -287,7 +470,7 @@ static OfClass ofClass(ClassDesc className) {
          * {@return an annotation element for a string-valued element}
          * @param value the string
          */
    -    static OfConstant ofString(Utf8Entry value) {
    +    static OfString ofString(Utf8Entry value) {
             return new AnnotationImpl.OfStringImpl(value);
         }
     
    @@ -295,7 +478,7 @@ static OfConstant ofString(Utf8Entry value) {
          * {@return an annotation element for a string-valued element}
          * @param value the string
          */
    -    static OfConstant ofString(String value) {
    +    static OfString ofString(String value) {
             return ofString(TemporaryConstantPool.INSTANCE.utf8Entry(value));
         }
     
    @@ -303,7 +486,7 @@ static OfConstant ofString(String value) {
          * {@return an annotation element for a double-valued element}
          * @param value the double value
          */
    -    static OfConstant ofDouble(DoubleEntry value) {
    +    static OfDouble ofDouble(DoubleEntry value) {
             return new AnnotationImpl.OfDoubleImpl(value);
         }
     
    @@ -311,7 +494,7 @@ static OfConstant ofDouble(DoubleEntry value) {
          * {@return an annotation element for a double-valued element}
          * @param value the double value
          */
    -    static OfConstant ofDouble(double value) {
    +    static OfDouble ofDouble(double value) {
             return ofDouble(TemporaryConstantPool.INSTANCE.doubleEntry(value));
         }
     
    @@ -319,7 +502,7 @@ static OfConstant ofDouble(double value) {
          * {@return an annotation element for a float-valued element}
          * @param value the float value
          */
    -    static OfConstant ofFloat(FloatEntry value) {
    +    static OfFloat ofFloat(FloatEntry value) {
             return new AnnotationImpl.OfFloatImpl(value);
         }
     
    @@ -327,7 +510,7 @@ static OfConstant ofFloat(FloatEntry value) {
          * {@return an annotation element for a float-valued element}
          * @param value the float value
          */
    -    static OfConstant ofFloat(float value) {
    +    static OfFloat ofFloat(float value) {
             return ofFloat(TemporaryConstantPool.INSTANCE.floatEntry(value));
         }
     
    @@ -335,7 +518,7 @@ static OfConstant ofFloat(float value) {
          * {@return an annotation element for a long-valued element}
          * @param value the long value
          */
    -    static OfConstant ofLong(LongEntry value) {
    +    static OfLong ofLong(LongEntry value) {
             return new AnnotationImpl.OfLongImpl(value);
         }
     
    @@ -343,7 +526,7 @@ static OfConstant ofLong(LongEntry value) {
          * {@return an annotation element for a long-valued element}
          * @param value the long value
          */
    -    static OfConstant ofLong(long value) {
    +    static OfLong ofLong(long value) {
             return ofLong(TemporaryConstantPool.INSTANCE.longEntry(value));
         }
     
    @@ -351,15 +534,15 @@ static OfConstant ofLong(long value) {
          * {@return an annotation element for an int-valued element}
          * @param value the int value
          */
    -    static OfConstant ofInt(IntegerEntry value) {
    -        return new AnnotationImpl.OfIntegerImpl(value);
    +    static OfInt ofInt(IntegerEntry value) {
    +        return new AnnotationImpl.OfIntImpl(value);
         }
     
         /**
          * {@return an annotation element for an int-valued element}
          * @param value the int value
          */
    -    static OfConstant ofInt(int value) {
    +    static OfInt ofInt(int value) {
             return ofInt(TemporaryConstantPool.INSTANCE.intEntry(value));
         }
     
    @@ -367,7 +550,7 @@ static OfConstant ofInt(int value) {
          * {@return an annotation element for a short-valued element}
          * @param value the short value
          */
    -    static OfConstant ofShort(IntegerEntry value) {
    +    static OfShort ofShort(IntegerEntry value) {
             return new AnnotationImpl.OfShortImpl(value);
         }
     
    @@ -375,7 +558,7 @@ static OfConstant ofShort(IntegerEntry value) {
          * {@return an annotation element for a short-valued element}
          * @param value the short value
          */
    -    static OfConstant ofShort(short value) {
    +    static OfShort ofShort(short value) {
             return ofShort(TemporaryConstantPool.INSTANCE.intEntry(value));
         }
     
    @@ -383,15 +566,15 @@ static OfConstant ofShort(short value) {
          * {@return an annotation element for a char-valued element}
          * @param value the char value
          */
    -    static OfConstant ofChar(IntegerEntry value) {
    -        return new AnnotationImpl.OfCharacterImpl(value);
    +    static OfChar ofChar(IntegerEntry value) {
    +        return new AnnotationImpl.OfCharImpl(value);
         }
     
         /**
          * {@return an annotation element for a char-valued element}
          * @param value the char value
          */
    -    static OfConstant ofChar(char value) {
    +    static OfChar ofChar(char value) {
             return ofChar(TemporaryConstantPool.INSTANCE.intEntry(value));
         }
     
    @@ -399,7 +582,7 @@ static OfConstant ofChar(char value) {
          * {@return an annotation element for a byte-valued element}
          * @param value the byte value
          */
    -    static OfConstant ofByte(IntegerEntry value) {
    +    static OfByte ofByte(IntegerEntry value) {
             return new AnnotationImpl.OfByteImpl(value);
         }
     
    @@ -407,7 +590,7 @@ static OfConstant ofByte(IntegerEntry value) {
          * {@return an annotation element for a byte-valued element}
          * @param value the byte value
          */
    -    static OfConstant ofByte(byte value) {
    +    static OfByte ofByte(byte value) {
             return ofByte(TemporaryConstantPool.INSTANCE.intEntry(value));
         }
     
    @@ -415,7 +598,7 @@ static OfConstant ofByte(byte value) {
          * {@return an annotation element for a boolean-valued element}
          * @param value the boolean value
          */
    -    static OfConstant ofBoolean(IntegerEntry value) {
    +    static OfBoolean ofBoolean(IntegerEntry value) {
             return new AnnotationImpl.OfBooleanImpl(value);
         }
     
    @@ -423,7 +606,7 @@ static OfConstant ofBoolean(IntegerEntry value) {
          * {@return an annotation element for a boolean-valued element}
          * @param value the boolean value
          */
    -    static OfConstant ofBoolean(boolean value) {
    +    static OfBoolean ofBoolean(boolean value) {
             int i = value ? 1 : 0;
             return ofBoolean(TemporaryConstantPool.INSTANCE.intEntry(i));
         }
    @@ -438,7 +621,7 @@ static OfAnnotation ofAnnotation(Annotation value) {
     
         /**
          * {@return an annotation element for an array-valued element}
    -     * @param values the values
    +     * @param values the array elements
          */
         static OfArray ofArray(List<AnnotationValue> values) {
             return new AnnotationImpl.OfArrayImpl(values);
    @@ -446,7 +629,7 @@ static OfArray ofArray(List<AnnotationValue> values) {
     
         /**
          * {@return an annotation element for an array-valued element}
    -     * @param values the values
    +     * @param values the array elements
          */
         static OfArray ofArray(AnnotationValue... values) {
             return ofArray(List.of(values));
    --- a/src/java.base/share/classes/java/lang/classfile/constantpool/AnnotationConstantValueEntry.java
    +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/AnnotationConstantValueEntry.java
     /**
    - * A constant pool entry that may be used as an annotation constant,
    - * which includes the four kinds of primitive constants, and UTF8 constants.
    + * A constant pool entry that may be used by annotation constant values,
    + * which includes the four kinds of primitive constants and UTF8 constants.
    + * These entries are also the only entries that do not refer to other
    + * constant pool entries.
      *
    + * @apiNote
    + * An annotation constant value entry alone is not sufficient to determine
    + * the annotation constant; for example, an {@link IntegerEntry} of {@code 1}
    + * can mean {@code true} in {@link AnnotationValue.OfBoolean} or {@code 1}
    + * in {@link AnnotationValue.OfInt}.
    + *
    + * @see AnnotationValue.OfConstant
      * @sealedGraph
      * @since 22
      */
    @@ -40,7 +50,8 @@ public sealed interface AnnotationConstantValueEntry extends PoolEntry
     
         /**
          * {@return the constant value}  The constant value will be an {@link Integer},
    -     * {@link Long}, {@link Float}, {@link Double}, or {@link String}.
    +     * {@link Long}, {@link Float}, {@link Double} for the primitive constants,
    +     * or {@link String} for UTF8 constants.
          */
         ConstantDesc constantValue();
     }
    --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolBuilder.java
    +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolBuilder.java
    @@ -510,25 +510,6 @@ default LoadableConstantEntry loadableConstantEntry(ConstantDesc c) {
             throw new IllegalArgumentException("Illegal type: " + (c == null ? null : c.getClass()));
         }
     
    -    /**
    -     * {@return An {@link AnnotationConstantValueEntry} describing the provided
    -     * constant}  The constant should be an Integer, String, Long, Float,
    -     * Double, ClassDesc (for a Class constant), or MethodTypeDesc (for a MethodType
    -     * constant.)
    -     *
    -     * @param c the constant
    -     */
    -    default AnnotationConstantValueEntry annotationConstantValueEntry(ConstantDesc c) {
    -        if (c instanceof Integer i) return intEntry(i);
    -        if (c instanceof String s) return utf8Entry(s);
    -        if (c instanceof Long l) return longEntry(l);
    -        if (c instanceof Float f) return floatEntry(f);
    -        if (c instanceof Double d) return doubleEntry(d);
    -        if (c instanceof ClassDesc cd) return utf8Entry(cd);
    -        if (c instanceof MethodTypeDesc mtd) return utf8Entry(mtd);
    -        throw new IllegalArgumentException("Illegal type: " + (c == null ? null : c.getClass()));
    -    }
    -
         /**
          * {@return a {@link BootstrapMethodEntry} describing the provided
          * bootstrap method and static arguments}
    
Comments
Moving to Approved.
13-08-2024

Updated some outdated comments in solutions section; ready for CSR review.
12-08-2024

Note that `@since` tags are not added for the renamed methods in anticipation of ClassFile API ending its preview status in JDK-8334712.
14-07-2024