在某些情况下,我们可以在不调用实例类的构造函数的情况下创建实例。这些案例有什么想法(非 Reflection API )?
答案 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)
涉及基于非构造函数的对象创建的两个“常见”案例是deserialization
和clone()
。
答案 2 :(得分:1)
我能想象的唯一案例是序列化和JNI。
通过序列化,您可以通过从输入流反序列化整个对象状态来创建新对象。在这种情况下,不会调用构造函数。
使用JNI,有AllocObject函数,它为新对象分配空间,也不调用构造函数。
编辑:对clone()
的调用可能会被视为另一种情况,但这取决于该方法的实施方式。
答案 3 :(得分:0)
有4种创建对象实例的方法
1)通过构造函数使用new
关键字 - 构造函数应该是可访问的
2)通过serialization/deserialization
- 该类应该是Serializable;
3)通过clone()方法 - 该方法应实现标记接口Cloneable
4)通过反射 - 您可以访问构造函数并在不使用new关键字的情况下创建实例。关于Reflection的最好的事情是它可以用于为私有构造函数实例化对象,前提是不会搞乱SecurityManager