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

时间:2010-11-09 12:37:49

标签: java reflection serialization constructor default-constructor

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

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

5 个答案:

答案 0 :(得分:30)

使用标准反射,不,但有一个库可以为您执行此操作:objenesis

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

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

答案 1 :(得分:19)

将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

中所述

答案 2 :(得分:6)

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

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

对于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;

答案 3 :(得分:3)

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

答案 4 :(得分:2)

如果您的类没有其他构造函数,那么编译器将为您创建一个。你可能有一个no-arg构造函数而没有意识到它。

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

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