我正在尝试生成字节码,它将在没有代码初始化逻辑的情况下创建对象实例。其实我想重现 generateSerializationConstructor 行为。

    {
        mv = cw.visitMethod(ACC_PUBLIC, "newObjectInstance", "()Ljava/lang/Object;", null, null);
        mv.visitCode();
        mv.visitTypeInsn(NEW, classNameInternal);
        mv.visitInsn(DUP);
        classNameInternal = "java/lang/Object";
        mv.visitMethodInsn(INVOKESPECIAL, classNameInternal, "<init>", "()V");
        mv.visitInsn(ARETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }
不幸的是我得到了这样的错误:

最佳答案

JVM 规范禁止在不调用正确构造函数的情况下创建对象。
但是,有两种棘手的方法可以做到这一点。
它们都特定于 OpenJDK/Oracle JDK,并不能保证适用于所有 Java 实现。

  • 调用 sun.misc.Unsafe.allocateInstance() 内部 API 来实例化一个类而不调用构造函数。
  • 在运行时生成类时,从 sun.reflect.MagicAccessorImpl 继承您的类。 JVM 将跳过此类类的字节码验证,从而允许在没有适当 INVOKESPECIAL 的情况下拥有新的字节码。

  • 这两种技术都用于我们的自定义序列化引擎,可以在 https://github.com/odnoklassniki/one-nio/blob/master/src/one/nio/serial/ 找到

    关于java - 在不调用初始化程序的情况下创建对象实例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22570413/

    10-10 14:37