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

问题描述 投票:0回答:6

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

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

java reflection serialization constructor default-constructor
6个回答
35
投票

使用标准反射,不行,但是有一个库可以为您做到这一点:objenesis

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

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


25
投票

将类实例作为变量 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

中所述

7
投票

您的解决方案将特定于 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
投票

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


2
投票

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

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

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


0
投票

可以使用 Java 反序列化对象时使用的相同机制:

ObjectStreamClass objectStreamClass = ObjectStreamClass.lookup(MyClass.class);
Method newInstance = ObjectStreamClass.getClass().getDeclaredMethod("newInstance");
newInstance.setAccessible(true);
Object instance = newInstance.invoke(objectStreamClass);
© www.soinside.com 2019 - 2024. All rights reserved.