Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

Ответ 3

Ваше решение будет специфичным для 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;

Ответ 4

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

Ответ 5

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

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

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

Ответ 6

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