import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Type;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.commons.GeneratorAdapter;
import com.esotericsoftware.reflectasm.MethodAccess;
public class ReflectASMExample {
public static void main(String[] args) throws Exception {
ASMClassLoader classLoader = new ASMClassLoader();
ReflectASM reflectASM = ReflectASM.create(classLoader);
String className = "com.example.TestClass";
String classDescriptor = Type.getDescriptor(TestClass.class);
MethodVisitor visitMethod = reflectASM.visitMethod(Opcodes.ACC_PUBLIC, "helloWorld", "()V", null, null);
visitMethod.visitCode();
visitMethod.visitLdcInsn("Hello, World!");
visitMethod.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/System", "out", Type.getMethodDescriptor(Type.getType(java.io.PrintStream.class), Type.getType(String.class)), false);
visitMethod.visitInsn(Opcodes.RETURN);
visitMethod.visitMaxs(1, 1);
visitMethod.visitEnd();
FieldVisitor visitField = reflectASM.visitField(Opcodes.ACC_PUBLIC, "testField", Type.getDescriptor(String.class), null, null);
visitField.visitEnd();
ClassWriter cw = reflectASM.getClassWriter();
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, className, null, "java/lang/Object", null);
cw.visitSource(className, null);
cw.visitEnd();
Class<?> generatedClass = classLoader.defineClass(className, cw.toByteArray());
TestClass testInstance = (TestClass) generatedClass.getDeclaredConstructor().newInstance();
MethodAccess methodAccess = reflectASM.getMethodAccess(generatedClass);
methodAccess.invoke(testInstance, "helloWorld");
testInstance.setTestField("Test Field Value");
String testFieldValue = (String) testInstance.getTestField();
System.out.println("Test Field Value: " + testFieldValue);
}
}
class TestClass {
public void helloWorld() {
System.out.println("Hello, World!");
}
public String testField;
}
class ASMClassLoader extends ClassLoader {
public Class<?> defineClass(String name, byte[] b) {
return super.defineClass(name, b, 0, b.length);
}
}