Summary
Add ConstantDesc.internalName and change ConstantDesc.ofInternalName to be its inverse; together, they handle conversion between ClassDesc and string representation of CONSTANT_Class_info.
Problem
Conversion between ClassDesc and CONSTANT_Class_info was inconsistent: primitives can't be converted, arrays use their descriptors, and classes or interfaces use a custom "internal name", which sees no usage elsewhere. Users of ClassDesc were forced to resort to custom solutions for conversion in both ways, including the previous addition of ClassDesc.ofInternalName.
Solution
Add a new API, internalName(), to ClassDesc that reliably converts a ClassDesc into a String for CONSTANT_Class_info, or throw an IllegalStateException if it cannot. Modify the existing ofInternalName(String) API to accept all valid String for CONSTANT_Class_info. Discuss about CONSTANT_Class_info in the ClassDesc class specification. Remove irrelevant references to CONSTANT_Class_info elsewhere within ClassDesc.
Specification
See https://cr.openjdk.org/~liach/8306700/0/java.base/java/lang/constant/ClassDesc.html for rendered version.
--- a/src/java.base/share/classes/java/lang/constant/ClassDesc.java
+++ b/src/java.base/share/classes/java/lang/constant/ClassDesc.java
@@ -50,6 +50,16 @@ import static java.util.stream.Collectors.joining;
* {@linkplain ClassDesc} for the component type and then call the {@link #arrayType()}
* or {@link #arrayType(int)} methods.
*
+ * <h2 id="constant-class-info">The {@code CONSTANT_Class_info} Structure</h2>
+ *
+ * <p>While most appearances of {@link Class} constants are in the form of {@linkplain
+ * #descriptorString() descriptors}, in the {@code CONSTANT_Class_info} structure
+ * (JVMS {@jvms 4.4.1}), they appear as binary name encoded in internal forms,
+ * such as {@code "java/lang/String"} for {@link String} class. Such forms can be
+ * converted to ClassDesc with {@link #ofInternalName(String)} and retrieved from a
+ * {@linkplain ClassDesc} with {@link #internalName()}. In addition, primitive types
+ * cannot be encoded in the {@code CONSTANT_Class_info} structure.
+ *
* @see ConstantDescs
*
* @since 12
@@ -82,28 +92,29 @@ public sealed interface ClassDesc
}
/**
- * Returns a {@linkplain ClassDesc} for a class or interface type,
- * given the name of the class or interface in internal form,
- * such as {@code "java/lang/String"}.
- *
- * @apiNote
- * To create a descriptor for an array type, either use {@link #ofDescriptor(String)}
- * or {@link #arrayType()}; to create a descriptor for a primitive type, use
- * {@link #ofDescriptor(String)} or use the predefined constants in
- * {@link ConstantDescs}.
+ * {@return a {@linkplain ClassDesc} from a string representation
+ * in a {@link ##constant-class-info CONSTANT_Class_info} structure}
*
- * @param name the fully qualified class name, in internal (slash-separated) form
- * @return a {@linkplain ClassDesc} describing the desired class
+ * @param name the class name, compliant with requirements of the
+ * {@code CONSTANT_Class_info} structure
* @throws NullPointerException if the argument is {@code null}
* @throws IllegalArgumentException if the name string is not in the
* correct format
- * @jvms 4.2.1 Binary Class and Interface Names
* @see ClassDesc#of(String)
* @see ClassDesc#ofDescriptor(String)
+ * @see ClassDesc#internalName()
+ * @see <a href="#constant-class-info">The {@code CONSTANT_Class_info} Structure</a>
* @since 20
*/
static ClassDesc ofInternalName(String name) {
}
@@ -153,7 +164,6 @@ public sealed interface ClassDesc
* @throws IllegalArgumentException if the name string is not in the
* correct format
* @jvms 4.3.2 Field Descriptors
- * @jvms 4.4.1 The CONSTANT_Class_info Structure
* @see ClassDesc#of(String)
* @see ClassDesc#ofInternalName(String)
*/
@@ -181,7 +191,6 @@ public sealed interface ClassDesc
* @return a {@linkplain ClassDesc} describing the array type
* @throws IllegalStateException if the resulting {@linkplain
* ClassDesc} would have an array rank of greater than 255
- * @jvms 4.4.1 The CONSTANT_Class_info Structure
*/
default ClassDesc arrayType() {
int depth = ConstantUtils.arrayDepth(descriptorString());
@@ -202,7 +211,6 @@ public sealed interface ClassDesc
* @throws IllegalArgumentException if the rank is less than or
* equal to zero or if the rank of the resulting array type is
* greater than 255
- * @jvms 4.4.1 The CONSTANT_Class_info Structure
*/
default ClassDesc arrayType(int rank) {
int netRank;
@@ -355,6 +363,23 @@ public sealed interface ClassDesc
throw new IllegalStateException(descriptorString());
}
+ /**
+ * {@return the string representation of this {@linkplain ClassDesc} in a
+ * {@link ##constant-class-info CONSTANT_Class_info} structure}
+ *
+ * @apiNote
+ * In a future release, this API may return a value instead of throwing
+ * an exception if this {@linkplain ClassDesc} becomes representable in a
+ * {@code CONSTANT_Class_info}.
+ *
+ * @throws IllegalStateException if this {@linkplain ClassDesc} describes a type
+ * that cannot be represented by a {@code CONSTANT_Class_info}, such as primitive types
+ * @see ClassDesc#ofInternalName(String)
+ * @see <a href="#constant-class-info">The {@code CONSTANT_Class_info} Structure</a>
+ * @since 21
+ */
+ String internalName();
+
/**
* Returns a field type descriptor string for this type
*
- csr of
-
JDK-8306697 Add method to obtain String for CONSTANT_Class_info in ClassDesc
-
- Closed
-