39

我有一个没有默认构造函数的类。我需要一种方法来获取此类的“空白”实例。“空白”表示实例化后所有类字段都应具有默认值,如 null、0 等。

我问是因为我需要能够序列化/去序列化大树的对象。而且我无法访问这些对象类的来源,并且类既没有默认构造函数也没有实现可序列化。尝试序列化这种结构可能不是一个好主意,但另一种方法是将其转换为更容易序列化的东西。

4

5 回答 5

35

使用标准反射,不,但是有一个库可以为你做这件事:objenesis

它专门设计用于在没有默认构造函数的情况下实例化类,并且它被其他序列化库(如xstream )使用。

注意:在这些情况下可能不会调用构造函数(但这可能是您想要的)。

于 2010-11-09T12:46:55.397 回答
25

将 Class 实例作为变量 clazz 提供:

ReflectionFactory rf = ReflectionFactory.getReflectionFactory();
Constructor objDef = parent.getDeclaredConstructor();
Constructor intConstr = rf.newConstructorForSerialization(clazz, objDef);
clazz.cast(intConstr.newInstance());

http://www.javaspecialists.eu/archive/Issue175.html中所述

于 2010-11-09T12:51:28.487 回答
7

您的解决方案将特定于 JVM。

如果您需要便携式解决方案,请使用 3rd 方库

对于 Sun 的 JVM v1.5,您可以这样做:

    final Class<?> myClass = MyClass.class;
    final ReflectionFactory reflection = ReflectionFactory.getReflectionFactory();
    final Constructor<Object> constructor = 
        reflection.newConstructorForSerialization(
            myClass, Object.class.getDeclaredConstructor(new Class[0]));
    final Object o = constructor.newInstance(new Object[0]);

    System.out.print(o.getClass());

XStream 中的相关类是:

  • com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider
  • com.thoughtworks.xstream.core.JVM;
于 2010-11-09T13:02:14.967 回答
3

我能想到的唯一解决方案是使用诸如javassist之类的字节码操作库来添加默认构造函数。

于 2010-11-09T12:47:03.880 回答
2

如果您的类没有其他构造函数,那么编译器将为您创建一个。您可能有一个无参数的构造函数并且没有意识到它。

如果您不编写无参数构造函数,并且您甚至包含一个带参数的构造函数,那么编译器不会给您一个。反射也无济于事:如果您尝试找到一个无参数构造函数并且没有,那么您期望会发生什么?

听起来您不能使用 java.lang.Serializable 使用 Java 对象序列化,但这不是您唯一的选择。您还可以使用 XML、JSON、原型缓冲区或任何其他方便的协议。

于 2010-11-09T12:46:22.493 回答