Cómo extender una clase en tiempo de ejecución en Java?

RB Méndez:

Me gustaría crear un software de auto-programación, hay una manera de extender una clase en tiempo de ejecución y algo que faciliten la generación de código fuente?

Mar:

Usted puede tratar con el componente ClassFactory y las fuentes de generación de componentes de Burningwave Core . Por ejemplo:

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();
    }
}

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=367230&siteId=1
Recomendado
Clasificación