如何在不调用此类的构造函数的情况下创建类的实例?

时间:2014-08-22 13:12:40

标签: java

在某些情况下,我们可以在不调用实例类的构造函数的情况下创建实例。这些案例有什么想法(非 Reflection API )?

4 个答案:

答案 0 :(得分:5)

这是打破你的系统的可靠方法,但至少它不会调用构造函数。使用Unsafe#allocateInstance(Class)

import java.lang.reflect.Field;
import sun.misc.Unsafe;

public class Example {
    private String value = "42";
    public static void main(String[] args) throws Exception {
        Example instance = (Example) unsafe.allocateInstance(Example.class);
        System.out.println(instance.value);
    }

    static Unsafe unsafe;
    static {
        try {

            Field singleoneInstanceField = Unsafe.class.getDeclaredField("theUnsafe");
            singleoneInstanceField.setAccessible(true);
            unsafe = (Unsafe) singleoneInstanceField.get(null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

打印

null

表示未调用Example默认构造函数。

答案 1 :(得分:4)

涉及基于非构造函数的对象创建的两个“常见”案例是deserializationclone()

答案 2 :(得分:1)

我能想象的唯一案例是序列化和JNI。

通过序列化,您可以通过从输入流反序列化整个对象状态来创建新对象。在这种情况下,不会调用构造函数。

使用JNI,有AllocObject函数,它为新对象分配空间,也不调用构造函数。

编辑:对clone()的调用可能会被视为另一种情况,但这取决于该方法的实施方式。

答案 3 :(得分:0)

有4种创建对象实例的方法

1)通过构造函数使用new关键字 - 构造函数应该是可访问的

2)通过serialization/deserialization - 该类应该是Serializable;

3)通过clone()方法 - 该方法应实现标记接口Cloneable

4)通过反射 - 您可以访问构造函数并在不使用new关键字的情况下创建实例。关于Reflection的最好的事情是它可以用于为私有构造函数实例化对象,前提是不会搞乱SecurityManager