Возможно ли в java создать "пустой" экземпляр класса без конструктора no-arg с помощью отражения?

У меня есть класс, который не имеет конструктора по умолчанию. И мне нужен способ получить "пустой" экземпляр этого класса. "пустой" означает, что после создания экземпляра все поля класса должны иметь значения по умолчанию как null, 0 и т. д.

Я спрашиваю, потому что мне нужно иметь возможность сериализовать/дезириализовать большое дерево объектов. И у меня нет доступа к источникам этих классов объектов, а классы не имеют ни конструкторов по умолчанию, ни реализаций serializable. Вероятно, не очень хорошая идея попытаться сериализовать такая структура, но альтернативой является ее преобразование в нечто более легко сериализуемое.

6 ответов


стандартные отражение, нет, но есть библиотека, которая может сделать это за вас: objenesis.

Он специально разработан для создания экземпляров классов без конструкторов по умолчанию и используется другими библиотеками сериализации, такими как кинокомпании xStream.

Примечание: конструктор не может быть вызван в этих случаях (но это предположительно то, что вы хотите).


имея экземпляр класса, предоставленный как переменная 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


ваше решение будет специфичным для JVM.

Если вам нужно портативное решение, используйте стороннюю библиотеку.

для Sun JVM для запуска В1.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.конвертеры.отображение.PureJavaReflectionProvider
  • com.thoughtworksбыл.кинокомпании xStream.ядро.Для JVM;

единственное решение, которое я могу придумать, - это использовать библиотеку манипуляций байт-кодом, такую как javassist добавить конструктор по умолчанию.


Если у вашего класса нет другого конструктора, компилятор создаст его для вас. Возможно, у вас есть конструктор no-arg и вы этого не понимаете.

Если вы не пишете конструктор no-arg, и вы включаете еще один конструктор, который принимает аргумент, тогда компилятор не даст вам его. Отражение тоже не поможет: если вы попытаетесь найти конструктор без arg, а его нет,что вы ожидаете?

не похоже, что вы можете используйте сериализацию объектов Java с помощью java.ленг.Сериализуемый, но это не единственный выбор. Вы также можете использовать XML, или JSON, или буферы прототипов, или любой другой удобный протокол.


проверьте его: посмотрите, если yourObject.класс.newInstace() работы. Если нет, то все, о чем я могу думать, - это создать объект-прототип, вызвав обычный конструктор, установить его поля в ноль, а затем клонировать его.