-
CSR
-
Resolution: Approved
-
P4
-
None
-
source
-
minimal
-
Changes to preview APIs involve minimal risk.
-
Java API
-
SE
Summary
Add ConstantPool.entryByIndex and ClassReader.readEntryOrNull, and remove ClassReader.utf8EntryByIndex.
Problem
Many constant pool references in ClassFile structures are restricted to a particular type, otherwise it's an error; for example, the superclass pointer can be 0 (null) or a valid CONSTANT_Class index, but not a CONSTANT_Utf8 index. However, the methods in ClassFile API only provides a readEntryOrNull without type checking, and a cast to ClassEntry may cause ClassCastException, which is out of spec with ClassFile API throwing IllegalArgumentException for malformed Class-Files.
Solution
- Add overloads to ConstantPool.entryByIndex and ClassReader.readEntryOrNull.
- Remove ClassReader.utf8EntryByIndex; users can use ConstantPool.entryByIndex(index, Utf8Entry.class).
- Add API notes on entryByIndex, readEntry, readEntryOrNull to recommend using type-checked methods to access constant pool if there's a type restriction.
Specification
--- a/src/java.base/share/classes/java/lang/classfile/ClassReader.java
+++ b/src/java.base/share/classes/java/lang/classfile/ClassReader.java
@@ -89,17 +89,14 @@ public sealed interface ClassReader extends ConstantPool
// Constant pool
- /**
- * {@return the UTF8 constant pool entry at the given index of the constant
- * pool} The given index must correspond to a valid constant pool index
- * whose slot holds a UTF8 constant.
- * @param index the index into the constant pool
- */
- Utf8Entry utf8EntryByIndex(int index);
-
/**
* {@return the constant pool entry whose index is given at the specified
* offset within the classfile}
+ *
+ * @apiNote
+ * If only a particular type of entry is expected, use {@link #readEntry(
+ * int, Class) readEntry(int, Class)}.
+ *
* @param offset the offset of the index within the classfile
* @throws ConstantPoolException if the index is out of range of the
* constant pool size, or zero
@@ -121,12 +118,31 @@ public sealed interface ClassReader extends ConstantPool
* {@return the constant pool entry whose index is given at the specified
* offset within the classfile, or null if the index at the specified
* offset is zero}
+ *
+ * @apiNote
+ * If only a particular type of entry is expected, use {@link #readEntryOrNull(
+ * int, Class) readEntryOrNull(int, Class)}.
+ *
* @param offset the offset of the index within the classfile
* @throws ConstantPoolException if the index is out of range of the
* constant pool size
*/
PoolEntry readEntryOrNull(int offset);
+ /**
+ * {@return the constant pool entry of a given type whose index is given
+ * at the specified offset within the classfile, or null if the index at
+ * the specified offset is zero}
+ *
+ * @param <T> the entry type
+ * @param offset the offset of the index within the classfile
+ * @param cls the entry type
+ * @throws ConstantPoolException if the index is out of range of the
+ * constant pool size, or zero, or the entry is not of the given type
+ * @since 24
+ */
+ <T extends PoolEntry> T readEntryOrNull(int offset, Class<T> cls);
+
/**
* {@return the UTF8 entry whose index is given at the specified
* offset within the classfile}
--- a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPool.java
+++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPool.java
@@ -46,6 +46,10 @@ public sealed interface ConstantPool extends Iterable<PoolEntry>
/**
* {@return the entry at the specified index}
*
+ * @apiNote
+ * If only a particular type of entry is expected, use {@link #entryByIndex(
+ * int, Class) entryByIndex(int, Class)}.
+ *
* @param index the index within the pool of the desired entry
* @throws ConstantPoolException if the index is out of range of the
* constant pool, or is considered unusable
@@ -57,6 +61,18 @@ public sealed interface ConstantPool extends Iterable<PoolEntry>
*/
int size();
+ /**
+ * {@return the entry of a given type at the specified index}
+ *
+ * @param <T> the entry type
+ * @param index the index within the pool of the desired entry
+ * @param cls the entry type
+ * @throws ConstantPoolException if the index is out of range of the
+ * constant pool, or the entry is not of the given type
+ * @since 24
+ */
+ <T extends PoolEntry> T entryByIndex(int index, Class<T> cls);
+
/**
* {@return an iterator over pool entries}
*/
- csr of
-
JDK-8332614 Type-checked ConstantPool.entryByIndex and ClassReader.readEntryOrNull
-
- Resolved
-