-
CSR
-
Resolution: Approved
-
P4
-
None
-
behavioral
-
minimal
-
Clarify existing specification.
-
Java API
-
SE
Summary
Update the API note of Class::getName
, MethodType::fromMethodDescriptorString
, and MethodType::toMethodDescriptorString
to mention valid descriptors, distinct class loaders, and requirements for a truly inverse recovery of MethodType from a method type descriptor.
Problem
- Class::descriptorString is not a partial inverse of Class::forName; Class::getName is when it returns a binary name.
- MethodType::toMethodDescriptorString has typos, and it and fromMethodDescriptorString doesn't mention hidden classes (whose resulting method types don't have method type descriptors) cannot be described nominally/constructed from descriptor.
Solution
- Add a note about classes having same name but distinct loaders in getName, and remove the API notes from Class::descriptorString. (Note: JDK-8310242 mentions the relationship of getName and forName in forName's specification)
- Update MethodType::fromMethodDescriptorString to refer to method descriptors in JVMS to take non-nominally-describable classes into account
- Fix typos in MethodType::toMethodDescriptorString.
Specification
--- a/src/java.base/share/classes/java/lang/Class.java
+++ b/src/java.base/share/classes/java/lang/Class.java
@@ -946,6 +946,9 @@ public final class Class<T> implements java.io.Serializable,
* returns "[[[[[[[I"
* </pre></blockquote>
*
+ * @apiNote
+ * Distinct class objects can have the same name but different class loaders.
+ *
* @return the name of the class, interface, or other entity
* represented by this {@code Class} object.
* @jls 13.1 The Form of a Binary
@@ -4562,11 +4565,6 @@ public final class Class<T> implements java.io.Serializable,
* is a one-letter code corresponding to a primitive type or {@code void}
* ({@code "B", "C", "D", "F", "I", "J", "S", "Z", "V"}) (JVMS {@jvms 4.3.2}).
*
- * @apiNote
- * This is not a strict inverse of {@link #forName};
- * distinct classes which share a common name but have different class loaders
- * will have identical descriptor strings.
- *
* @return the descriptor string for this {@code Class} object
* @jvms 4.3.2 Field Descriptors
* @since 12
--- a/src/java.base/share/classes/java/lang/invoke/MethodType.java
+++ b/src/java.base/share/classes/java/lang/invoke/MethodType.java
@@ -1159,26 +1158,29 @@ class MethodType
}
/**
- * Finds or creates an instance of a method type, given the spelling of its bytecode descriptor.
- * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * Finds or creates an instance of a method type of the given method descriptor
+ * (JVMS {@jvms 4.3.3}). This method is a convenience method for
+ * {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
* Any class or interface name embedded in the descriptor string will be
- * resolved by the given loader (or if it is null, on the system class loader).
- * <p>
- * Note that it is possible to encounter method types which cannot be
- * constructed by this method, because their component types are
- * not all reachable from a common class loader.
+ * resolved by the given loader (or if it is {@code null}, on the system class loader).
+ *
+ * @apiNote
+ * It is possible to encounter method types that have valid descriptors but
+ * cannot be constructed by this method, because their component types are
+ * not visible from a common class loader.
* <p>
* This method is included for the benefit of applications that must
* generate bytecodes that process method handles and {@code invokedynamic}.
- * @param descriptor a bytecode-level type descriptor string "(T...)T"
+ * @param descriptor a method descriptor string
* @param loader the class loader in which to look up the types
- * @return a method type matching the bytecode-level type descriptor
- * @throws NullPointerException if the string is null
- * @throws IllegalArgumentException if the string is not well-formed
+ * @return a method type of the given method descriptor
+ * @throws NullPointerException if the string is {@code null}
+ * @throws IllegalArgumentException if the string is not a method descriptor
* @throws TypeNotPresentException if a named type cannot be found
* @throws SecurityException if the security manager is present and
* {@code loader} is {@code null} and the caller does not have the
* {@link RuntimePermission}{@code ("getClassLoader")}
+ * @jvms 4.3.3 Method Descriptors
*/
public static MethodType fromMethodDescriptorString(String descriptor, ClassLoader loader)
throws IllegalArgumentException, TypeNotPresentException
@@ -1218,19 +1220,20 @@ class MethodType
}
/**
- * Returns a descriptor string for the method type. This method
+ * {@return the descriptor string for this method type} This method
* is equivalent to calling {@link #descriptorString() MethodType::descriptorString}.
*
- * <p>
- * Note that this is not a strict inverse of {@link #fromMethodDescriptorString fromMethodDescriptorString}.
- * Two distinct classes which share a common name but have different class loaders
- * will appear identical when viewed within descriptor strings.
+ * @apiNote
+ * This is not a strict inverse of {@link #fromMethodDescriptorString
+ * fromMethodDescriptorString} which requires a method type descriptor
+ * (JVMS {@jvms 4.3.3}) and a suitable class loader argument.
+ * Two distinct {@code MethodType} objects can have an identical
+ * descriptor string as distinct classes can have the same name
+ * but different class loaders.
+ *
* <p>
* This method is included for the benefit of applications that must
* generate bytecodes that process method handles and {@code invokedynamic}.
- * {@link #fromMethodDescriptorString(java.lang.String, java.lang.ClassLoader) fromMethodDescriptorString},
- * because the latter requires a suitable class loader argument.
- * @return the descriptor string for this method type
* @jvms 4.3.3 Method Descriptors
* @see <a href="#descriptor">Nominal Descriptor for {@code MethodType}</a>
*/
Rendered specifications:
https://cr.openjdk.org/~liach/8309819/09/java.base/java/lang/Class.html
https://cr.openjdk.org/~liach/8309819/09/java.base/java/lang/invoke/MethodType.html
- csr of
-
JDK-8309819 Clarify API note in Class::getName and MethodType::toMethodDescriptorString
-
- Resolved
-