Question

I have a class which has not default constructor. And I need a way to get 'blank' instance of this class. 'blank' means that after instantiation all class fields should has default values like null, 0 etc.

I'm asking because I need to be able serialize/desirialize big tree of objects. And I have no access to sources of this objects classes and classes has neither default constructors nor implements serializable. It is likely not very good idea to try to serialize such structure but the alternative is to convert it to something more easily serializable.

Was it helpful?

Solution

With standard reflection, no, but there is a library that can do it for you: objenesis.

It's specifically designed to instantiate classes without default constructors, and it's used by other serialization libraries like xstream.

Note: the constructor might not be called in these cases (but that's presumably what you want).

OTHER TIPS

Having Class instance provided as variable clazz:

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

as described in http://www.javaspecialists.eu/archive/Issue175.html

Your solution will be JVM specific.

If you need a portable solution use a 3rd party library.

For Sun's JVM v1.5 you can do this:

    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());

The relevant classes in XStream are:

  • com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider
  • com.thoughtworks.xstream.core.JVM;

The only solution I can think of would be to use a bytecode manipulation library such as javassist to add a default constructor.

If your class has no other constructor, then the compiler will create one for you. You might have a no-arg constructor and not realize it.

If you do not write a no-arg constructor, and you include even one constructor that takes an argument, then the compiler will not give you one. Reflection won't help, either: if you try to find a no-arg constructor and there isn't one, what do you expect to happen?

It doesn't sound like you can use Java object serialization using java.lang.Serializable, but that's not your only choice. You can also use XML, or JSON, or prototype buffers, or any other protocol that's convenient.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top