The point here is that the constructor might be synthetic, in which case it can't be called
directly from Java source code. Say we want to call the constructor ConstructMe(int,
String, long) with parameters 1, "2", 3L. If the constructor is synthetic, then Java
source code can't just do new ConstructMe(1, "2", 3L). So this class allows you to
generate a class file, say Forwarder, that is basically what you would get if you could
compile this:
final class Forwarder {
private Forwarder() {}
static ConstructMe of(int a, String b, long c) {
return new ConstructMe(a, b, c);
}
}
Because the class file is assembled directly, rather than being produced by the Java compiler,
it can call the synthetic constructor. Then regular Java source code can do Forwarder.of(1, "2", 3L) to call the constructor.
| Access | Constructor and Description |
|---|---|
| private |
| Modifier and Type | Method and Description |
|---|---|
| private static String | |
| private static String | internalName(javax.
Given a class like |
| private static int | loadInstruction(javax.
The bytecode instruction that copies a parameter of the given type onto the JVM stack. |
| private static int | localSize(javax.
The size in the local variable array of a value of the given type. |
| pack-priv static byte[] | Returns: a byte array making up the new class filethe fully-qualified name of the class to generate forwardingClassName, javax.the type whose constructor will be invoked ( classToConstruct,ConstructMe in the
example above)the erased types of the constructor parameters, which will also be
the types of the generated constructorParametersof method. We require the types to be erased so as not
to require an instance of the Types interface to erase them here. Having to deal
with generics would complicate things unnecessarily.Assembles a class with a static method |
| private static String |
| ForwardingClassGenerator | back to summary |
|---|---|
| private ForwardingClassGenerator() | |
| internalName | back to summary |
|---|---|
| private static String internalName(String className) | |
| internalName | back to summary |
|---|---|
| private static String internalName(javax. Given a class like | |
| loadInstruction | back to summary |
|---|---|
| private static int loadInstruction(javax. The bytecode instruction that copies a parameter of the given type onto the JVM stack. | |
| localSize | back to summary |
|---|---|
| private static int localSize(javax. The size in the local variable array of a value of the given type. A quirk of the JVM means that long and double variables each take up two consecutive slots in the local variable array. (The first n local variables are the parameters, so we need to know their sizes when iterating over them.) | |
| makeConstructorForwarder | back to summary |
|---|---|
| pack-priv static byte[] makeConstructorForwarder(String forwardingClassName, javax. Assembles a class with a static method It would be simpler if we could just pass in an
| |
| signatureEncoding | back to summary |
|---|---|
| private static String signatureEncoding(javax. | |