是否可以在现有实例上调用构造函数?

奥列格(Oleg Pyzhcov)

众所周知,使用sun.misc.Unsafe#allocateInstance它可以创建一个对象而无需调用任何类构造函数。

是否有可能做相反的事情:给定现有实例,在其上调用构造函数?


澄清:这不是我在生产代码中要做的事情的问题。我对JVM内部和仍然可以完成的疯狂事情感到好奇。欢迎提供特定于某些JVM版本的答案。

脂蛋白

JVMS§2.9禁止在已初始化的对象上调用构造函数:

实例初始化方法只能由invokespecial指令在Java虚拟机内调用,并且只能在未初始化的类实例上调用。

但是,从技术上讲,仍然可以使用JNI在初始化的对象上调用构造函数CallVoidMethod函数<init>与普通Java方法没有区别而且,JNI规范暗示了CallVoidMethod 用于调用构造函数的提示,尽管它并未说明是否必须初始化实例:

当这些函数用于调用私有方法和构造函数时,方法ID必须从obj的真实类派生,而不是从其超类之一派生。

我已经验证了以下代码在JDK 8和JDK 9中均适用。JNI允许您执行不安全的操作,但您不应在生产应用程序中依赖此代码。

ConstructorInvoker.java

public class ConstructorInvoker {

    static {
        System.loadLibrary("constructorInvoker");
    }

    public static native void invoke(Object instance);
}

constructorInvoker.c

#include <jni.h>

JNIEXPORT void JNICALL
Java_ConstructorInvoker_invoke(JNIEnv* env, jclass self, jobject instance) {
    jclass cls = (*env)->GetObjectClass(env, instance);
    jmethodID constructor = (*env)->GetMethodID(env, cls, "<init>", "()V");
    (*env)->CallVoidMethod(env, instance, constructor);
}

TestObject.java

public class TestObject {
    int x;

    public TestObject() {
        System.out.println("Constructor called");
        x++;
    }

    public static void main(String[] args) {
        TestObject obj = new TestObject();
        System.out.println("x = " + obj.x);  // x = 1

        ConstructorInvoker.invoke(obj);
        System.out.println("x = " + obj.x);  // x = 2
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

是否可以在已经创建的实例上直接调用构造函数?

是否可以在Java中创建对象的实例而无需调用构造函数?

构造函数是否可以调用自身?

构造函数的“实例”是否有严格的定义?

是否可以从move构造函数调用默认构造函数?

是否可以实例化具有删除的构造函数和析构函数的非聚合类?

是否可以动态分派在具有vtable的类上调用非虚拟函数?

有没有一种简单的方法可以在对象向量上调用构造函数?

使用构造函数类制作现有类实例的副本

在C#中是否可以强制私有函数只能从构造函数中调用?

是否可以编辑现有属性集函数调用的 CIL (MSIL) 指令?

是否可以在构造函数中调用函数?的PHP

我应该在原型上还是在新创建的实例上调用构造函数方法?

是否可以在JavaScript构造函数中分解实例/成员变量?

在C结构上调用默认构造函数

构造函数在return语句上调用

在构造函数方法上调用方法

确定构造函数是否在JavaScript构造函数设计模式中的同一元素上调用

从Java的构造函数中调用抽象方法是否可以?

是否可以从对象定义构造函数调用方法

除了对每个元素进行函数调用之外,是否还有更通用的方法可以在HTML元素上调用JS函数?

在没有复制删除的情况下,是否可以确保在析构函数之前调用复制/移动构造函数?

可以在函数上调用函数吗?

在Java中是否可以使用反射创建没有no-arg构造函数的类的“空白”实例?

当只有一个参数c#时,是否可以通过反射创建实例并指定重载的“ params”构造函数?

std::map 在 [] 上调用默认构造函数,在 insert() 上调用复制构造函数

调用SequenceType.forEach时是否可以引用实例函数?

是否可以在类/结构实例方法中调用GameScene函数?

是否可以从基类构造函数调用派生类构造函数?