/** Reflect operations demo */ public static void reflect(Object obj) { // `cls用于描述对象所属的类` Class cls = obj.getClass(); print("Class Name: " + cls.getCanonicalName()); // `fields包含对象的所有属性` Field[] fields = cls.getDeclaredFields(); print("List of fields:"); for (Field f : fields) { print(String.format("%30s %15s", f.getType(), f.getName())); } // `methods包含对象的所有方法` Method[] methods = cls.getDeclaredMethods(); print("List of methods:"); for (Method m : methods) print( String.format( "%30s %15s %30s", m.getReturnType(), m.getName(), Arrays.toString(m.getParameterTypes()))); Constructor[] constructors = cls.getConstructors(); print("List of contructors:"); for (Constructor c : constructors) print(String.format("%30s %15s", c.getName(), Arrays.toString(c.getParameterTypes()))); }
private static void generateCtor( ClassFileWriter cfw, String adapterName, String superName, Constructor<?> superCtor) { short locals = 3; // this + factory + delegee Class<?>[] parameters = superCtor.getParameterTypes(); // Note that we swapped arguments in app-facing constructors to avoid // conflicting signatures with serial constructor defined below. if (parameters.length == 0) { cfw.startMethod( "<init>", "(Laurora/javascript/Scriptable;" + "Laurora/javascript/ContextFactory;)V", ClassFileWriter.ACC_PUBLIC); // Invoke base class constructor cfw.add(ByteCode.ALOAD_0); // this cfw.addInvoke(ByteCode.INVOKESPECIAL, superName, "<init>", "()V"); } else { StringBuilder sig = new StringBuilder( "(Laurora/javascript/Scriptable;" + "Laurora/javascript/ContextFactory;"); int marker = sig.length(); // lets us reuse buffer for super signature for (Class<?> c : parameters) { appendTypeString(sig, c); } sig.append(")V"); cfw.startMethod("<init>", sig.toString(), ClassFileWriter.ACC_PUBLIC); // Invoke base class constructor cfw.add(ByteCode.ALOAD_0); // this short paramOffset = 3; for (Class<?> parameter : parameters) { paramOffset += generatePushParam(cfw, paramOffset, parameter); } locals = paramOffset; sig.delete(1, marker); cfw.addInvoke(ByteCode.INVOKESPECIAL, superName, "<init>", sig.toString()); } // Save parameter in instance variable "delegee" cfw.add(ByteCode.ALOAD_0); // this cfw.add(ByteCode.ALOAD_1); // first arg: Scriptable delegee cfw.add(ByteCode.PUTFIELD, adapterName, "delegee", "Laurora/javascript/Scriptable;"); // Save parameter in instance variable "factory" cfw.add(ByteCode.ALOAD_0); // this cfw.add(ByteCode.ALOAD_2); // second arg: ContextFactory instance cfw.add(ByteCode.PUTFIELD, adapterName, "factory", "Laurora/javascript/ContextFactory;"); cfw.add(ByteCode.ALOAD_0); // this for the following PUTFIELD for self // create a wrapper object to be used as "this" in method calls cfw.add(ByteCode.ALOAD_1); // the Scriptable delegee cfw.add(ByteCode.ALOAD_0); // this cfw.addInvoke( ByteCode.INVOKESTATIC, "aurora/javascript/JavaAdapter", "createAdapterWrapper", "(Laurora/javascript/Scriptable;" + "Ljava/lang/Object;" + ")Laurora/javascript/Scriptable;"); cfw.add(ByteCode.PUTFIELD, adapterName, "self", "Laurora/javascript/Scriptable;"); cfw.add(ByteCode.RETURN); cfw.stopMethod(locals); }