Skip to content

Editing classes

Editing classes

You can edit existing classes with ClassEditor and related editors like InterfacesEditor, AttributesEditor, and ConstantPoolEditor.

ClassEditor classEditor =
    new ClassEditor(targetClass);

classEditor.addField(field);

classEditor.addMethod(method);

If you want to create and add new fields or methods from scratch, you can use the more convenient ClassBuilder:

ProgramClass programClass =
    new ClassBuilder(existingClass)
        .addField(
            AccessConstants.PUBLIC |
            AccessConstants.STATIC,
            "someField",
            TypeConstants.INT);

        .addMethod(
            AccessConstants.PUBLIC |
            AccessConstants.STATIC,
            "main",
            "([Ljava/lang/String;)V",
            50,

            code -> code
                .getstatic("java/lang/System", "out", "Ljava/io/PrintStream;")
                .ldc("Hello, world!")
                .invokevirtual("java/io/PrintStream", "println", "(Ljava/lang/String;)V")
                .return_())

        .getProgramClass();

Editing code

Perhaps more interestingly, you can edit the bytecode of method bodies with CodeAttributeEditor.

CodeAttributeEditor codeAttributeEditor =
    new CodeAttributeEditor();

InstructionSequenceBuilder builder =
    new InstructionSequenceBuilder(targetClass);

Instructions[] replacementInstructions = builder
    .getstatic("java/lang/System", "out", "Ljava/io/PrintStream;")
    .ldc("Hello")
    .invokevirtual("java/io/PrintStream", "println", "(Ljava/lang/String;)V"        
    .instructions();

// Prepare the editor for this code.
codeAttributeEditor.reset(codeAttribute.u4codeLength);

// Insert the instruction sequence before a specified offset.
codeAttributeEditor.insertBeforeOffset(offset, replacementInstructions);

// Apply the changes.
codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute);