我们可以使用javassist创建实例对象而不使用反射吗?

我们可以使用javassist创建实例对象而不使用反射吗?,java,reflection,javassist,Java,Reflection,Javassist,如何使用javassist创建实例对象而不使用反射API Class cls = Class.forName("className"); Object obj = cls.getConstructor().newInstance(); CtClass ctClass = cp.get("className"); 如何在不使用反射API的情况下获取ctClass实例。像javassist这样的库不是用于反射,而是用于在运行时(修改已加载的类时需要插入)或在类加载之前生成/修改代码,但是。。。您

如何使用javassist创建实例对象而不使用反射API

Class cls = Class.forName("className");
Object obj = cls.getConstructor().newInstance();

CtClass ctClass = cp.get("className");

如何在不使用反射API的情况下获取ctClass实例。

像javassist这样的库不是用于反射,而是用于在运行时(修改已加载的类时需要插入)或在类加载之前生成/修改代码,但是。。。您仍然可以使用这样的库来生成调用某个方法的代码,因此最终您将执行与反射类似的操作并动态调用某个方法,但您仅限于可访问的方法,因此大多数情况下仅限于公共方法。(如果使用java 9,可以通过在同一个package+模块中定义类来调用包保护的类,但我将在这里跳过这一步)最后,您还需要使用反射——创建生成类的新实例,该实例将创建其他类的实例,而无需反射

在许多情况下,这样做是毫无意义的(虽然避免反射可能会节省一些执行时间,但在大多数情况下,这样做是不值得的,而且第一次调用会非常慢)。但如果你坚持的话,那就来吧:

public class Test {
    public static void main(String[] args) throws Exception {
        Supplier<Test> testSupplier = creatorFor(Test.class);
        // this is reflection free now:
        System.out.println(testSupplier.get());
        System.out.println(testSupplier.get());
    }

    private static <T> Supplier<T> creatorFor(Class<T> type) throws Exception {
        String toCreate = type.getName();
        ClassPool pool = ClassPool.getDefault();
        // create new class with some unique name
        CtClass generatorClass = pool.makeClass("generated." + toCreate + "Creator");
        // lets implement some common interface for easier usage
        generatorClass.addInterface(pool.getCtClass(Supplier.class.getName()));
        // and implement it method that will create new instance of our object
        CtMethod generatorMethod = CtNewMethod.make(
                "public Object get() { return new " + toCreate + "(); }",
                generatorClass);
        generatorClass.addMethod(generatorMethod);
        // the only reflective part we need:
        return (Supplier<T>) generatorClass.toClass().newInstance();
    }
}
公共类测试{
公共静态void main(字符串[]args)引发异常{
供应商testSupplier=creatorFor(Test.class);
//现在这是无反射的:
System.out.println(testSupplier.get());
System.out.println(testSupplier.get());
}
私有静态供应商creatorFor(类类型)引发异常{
String toCreate=type.getName();
ClassPool=ClassPool.getDefault();
//创建具有唯一名称的新类
CtClass generatorClass=pool.makeClass(“生成的“+toCreate+”创建者”);
//让我们实现一些通用接口,以便于使用
generatorClass.addInterface(pool.getCtClass(Supplier.class.getName());
//并实现它的方法,该方法将创建对象的新实例
CtMethod generatorMethod=CtNewMethod.make(
“public Object get(){return new”+toCreate+“();}”,
生成类);
generatorClass.addMethod(generatorMethod);
//我们唯一需要的反光部分是:
返回(供应商)generatorClass.toClass().newInstance();
}
}

为什么需要实例化CtClass。javassist库中的CtClass存储JVM中加载的任何类的字节码,提供的方法获取类属性、方法、构造函数等的详细信息,并在字节码级别修改类。据我所知,如果您需要重新实例化修改后的类,您应该使用Class.forName。对于反射操作,使用反射API有什么问题?昨天您提出了不同的问题,关于将反射API与javassist进行比较,以及其他一些问题。但这是苹果和橙子的比较。Javassist用于编辑类的字节码,而不是用于反射和动态调用。虽然。。。如果你坚持,我仍然可以告诉你如何创造这样的东西。