They are stored in Signature
attributes; see section 4.8.8 of the updated Java Virtual Machine Specification, as well as section 4.4.4 for the format of the field type signature.
Here’s an example using javap -verbose java.util.Map
:
public interface java.util.Map
SourceFile: "Map.java"
Signature: length = 0x2
00 1E
[other attributes omitted]
The Signature
attribute here specifies (if you read this as big-endian, like all integer quantities in the JVM class file format are) constant pool value #30 (30 = 0x1E). So let’s have a look there:
const #30 = Asciz <K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/lang/Object;;
Read this in the context of the grammar specified in 4.4.4. So, this uses two type parameters, K extends java.lang.Object
and V extends java.lang.Object
. The type itself (Map
) also extends class java.lang.Object
, and no interfaces.