如何在Java运行时扩展类? [关闭]

问题描述 投票:1回答:1

我想创建自编程软件,有没有一种方法可以在运行时扩展类,并且可以促进源代码的生成?

java code-generation runtime-compilation
1个回答
1
投票

您可以尝试使用ClassFactory组件和生成Burningwave Core组件的源。例如:

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();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.