// proxy
cv.visitField(ACC_PRIVATE, IH_FIELD, Type.getDescriptor(InvocationHandler.class), null, null);
// create a static adapter for generating a static initialiser method in
// the generated subclass
staticAdapter = new GeneratorAdapter(ACC_STATIC,
new Method("<clinit>", Type.VOID_TYPE, NO_ARGS), null, null, cv);
// add a constructor method that takes an invocation handler as an
// argument
Method m = new Method("<init>", Type.VOID_TYPE, new Type[] { IH_TYPE });
GeneratorAdapter methodAdapter = new GeneratorAdapter(ACC_PUBLIC, m, null, null, cv);
// loadthis
methodAdapter.loadThis();
// if we have java.* as a supertype call that zero args constructor
if (superclassBinaryName.startsWith("java.") || superclassBinaryName.startsWith("javax.")) {
methodAdapter.invokeConstructor(Type.getType(superclassClass), new Method("<init>",
Type.VOID_TYPE, NO_ARGS));
}
// otherwise invoke the java.lang.Object no args constructor
else {
methodAdapter.invokeConstructor(OBJECT_TYPE, new Method("<init>", Type.VOID_TYPE, NO_ARGS));
}
// call from the constructor to setInvocationHandler
Method setter = new Method("setInvocationHandler", Type.VOID_TYPE, new Type[] { IH_TYPE });
// load this
methodAdapter.loadThis();
// load the supplied invocation handler arg
methodAdapter.loadArgs();
// invoke the setter method
methodAdapter.invokeVirtual(newClassType, setter);
methodAdapter.returnValue();
methodAdapter.endMethod();
// add a method for getting the invocation handler
m = new Method("getInvocationHandler", IH_TYPE, NO_ARGS);
methodAdapter = new GeneratorAdapter(ACC_PUBLIC | ACC_FINAL, m, null, null, cv);
// load this to get the field
methodAdapter.loadThis();
// get the ih field and return
methodAdapter.getField(newClassType, IH_FIELD, IH_TYPE);
methodAdapter.returnValue();
methodAdapter.endMethod();
// add a method for setting the invocation handler
methodAdapter = new GeneratorAdapter(ACC_PUBLIC | ACC_FINAL, setter, null, null, cv);
// load this to put the field
methodAdapter.loadThis();
// load the method arguments (i.e. the invocation handler) to the stack
methodAdapter.loadArgs();
// set the ih field using the method argument
methodAdapter.putField(newClassType, IH_FIELD, IH_TYPE);
methodAdapter.returnValue();
methodAdapter.endMethod();
// loop through the class hierarchy to get any needed methods off the
// supertypes
// start by finding the methods declared on the class of interest (the
// superclass of our dynamic subclass)