Можно ли в Java создать «пустой» экземпляр класса без конструктора без аргументов, используя отражение? - PullRequest
33 голосов
/ 09 ноября 2010

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

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

Ответы [ 5 ]

31 голосов
/ 09 ноября 2010

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

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

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

19 голосов
/ 09 ноября 2010

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

6 голосов
/ 09 ноября 2010

Ваше решение будет зависеть от 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 голосов
/ 09 ноября 2010

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

2 голосов
/ 09 ноября 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...