How to extend a class at runtime in Java?

R.B. Mendez :

I would like to create self-programming software, is there a way to extend a class at runtime and something that facilitate source code generating?

Mrk :

You can try with ClassFactory component and sources generating components of Burningwave Core. For example:

package examples.classfactory;

import static org.burningwave.core.assembler.StaticComponentContainer.ConstructorHelper;

import java.lang.reflect.Modifier;

import org.burningwave.core.Virtual;
import org.burningwave.core.assembler.ComponentContainer;
import org.burningwave.core.assembler.ComponentSupplier;
import org.burningwave.core.classes.ClassFactory;
import org.burningwave.core.classes.ClassSourceGenerator;
import org.burningwave.core.classes.FunctionSourceGenerator;
import org.burningwave.core.classes.TypeDeclarationSourceGenerator;
import org.burningwave.core.classes.UnitSourceGenerator;

public class RuntimeClassExtender {

    public static void execute() throws Throwable {
        UnitSourceGenerator unitSG = UnitSourceGenerator.create("packagename").addClass(
            ClassSourceGenerator.create(
                TypeDeclarationSourceGenerator.create("MyExtendedClass")
            ).addModifier(
                Modifier.PUBLIC
            //generating new method that override MyInterface.getNumber()
            ).addMethod(
                FunctionSourceGenerator.create("getNumber")
                .setReturnType(Integer.class)
                .addModifier(Modifier.PUBLIC)
                .addOuterCodeRow("@Override")
                .addBodyCodeRow("return 1;")
            ).addConcretizedType(
                MyInterface.class
            ).expands(ToBeExtended.class)
        );
        System.out.println("\nGenerated code:\n" + unitSG.make());
        ComponentSupplier componentSupplier = ComponentContainer.getInstance();
        ClassFactory classFactory = componentSupplier.getClassFactory();
        Class<?> generatedClass =
            classFactory.getOrBuild(
            ExtendingClassOnRuntime.class.getClassLoader(),
            "packagename.MyExtendedClass",
            unitSG
            );
        ToBeExtended generatedClassObject =
            ConstructorHelper.newInstanceOf(generatedClass);
        generatedClassObject.printSomeThing();
        System.out.println(
            ((MyInterface)generatedClassObject).getNumber().toString()
        );
        //You can also invoke methods by casting to Virtual (an interface offered by the
        //library for faciliate use of runtime generated classes)
        Virtual virtualObject = (Virtual)generatedClassObject;
        //Invoke by using reflection
        virtualObject.invoke("printSomeThing");
        //Invoke by using MethodHandle
        virtualObject.invokeDirect("printSomeThing");
        System.out.println(
            ((Integer)virtualObject.invokeDirect("getNumber")).toString()
        );
    }   

    public static class ToBeExtended {

        public void printSomeThing() {
            System.out.println("Called");
        }

    }

    public static interface MyInterface {

        public Integer getNumber();

    }

    public static void main(String[] args) throws Throwable {
        execute();
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=366671&siteId=1