Возможно ли в 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() работы. Если нет, то все, о чем я могу думать, - это создать объект-прототип, вызвав обычный конструктор, установить его поля в ноль, а затем клонировать его.