Почему действительно В спящем режиме, не требуют никакого конструктора аргумента?

Конструктор без аргументов является требованием (инструментам нравится, в спящем режиме отражение использования об этом конструкторе для инстанцирования объектов).

Я получил этот ручной волнистый ответ, но кто-то мог объяснить далее?Спасибо

91
задан Mike Nakis 5 May 2015 в 22:49
поделиться

6 ответов

Hibernate и код в целом, который создает объекты посредством отражения, используют Class .newInstance () для создания нового экземпляра ваших классов. Этот метод требует, чтобы общедоступный конструктор без аргументов мог создать экземпляр объекта. В большинстве случаев использование конструктора без аргументов не является проблемой.

Существуют приемы, основанные на сериализации, которые могут обойтись без конструктора без аргументов, поскольку сериализация использует магию jvm для создания объектов без вызова конструктора. Но это доступно не для всех виртуальных машин. Например, XStream может создавать экземпляры объектов, у которых нет общедоступного конструктора без аргументов, но только в так называемом «расширенном» режиме, который доступен только на определенных виртуальных машинах. (Подробности см. По ссылке.) Разработчики Hibernate, безусловно, решили поддерживать совместимость со всеми виртуальными машинами и поэтому избегают таких уловок и используют официально поддерживаемый метод отражения Class .newInstance () , требующий no-arg конструктор.

126
ответ дан 24 November 2019 в 06:40
поделиться

Hibernate должен создавать экземпляры в результате ваших запросов (через отражение), Hibernate полагается на no-arg конструктор сущностей для этого, поэтому вам нужно предоставить no-arg конструктор. Что неясно?

5
ответ дан 24 November 2019 в 06:40
поделиться

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

В документации по спящему режиму говорится:

4.1.1. Реализуйте конструктор без аргументов

Все постоянные классы должны иметь конструктор по умолчанию (который может быть закрытым), чтобы Hibernate мог создавать их экземпляры с помощью Constructor.newInstance () . Рекомендуется иметь конструктор по умолчанию, по крайней мере, с видимостью пакета для создания прокси во время выполнения в Hibernate.

44
ответ дан 24 November 2019 в 06:40
поделиться

hibernate - это ORM-фреймворк, который поддерживает стратегию доступа к полям или свойствам. Однако, он не поддерживает отображение на основе конструкторов - возможно, то, что вы хотели бы? - Из-за некоторых проблем, таких как

Что происходит, если ваш класс содержит много конструкторов

public class Person {

    private String name;
    private Integer age;

    public Person(String name, Integer age) { ... }
    public Person(String name) { ... }
    public Person(Integer age) { ... }

}

Как вы видите, вы имеете дело с проблемой несогласованности, потому что Hibernate не может предположить, какой конструктор должен быть вызван. Например, предположим, вам нужно получить сохраненный объект Person

Person person = (Person) session.get(Person.class, <IDENTIFIER>);

Какой конструктор должен вызвать Hibernate, чтобы получить объект Person? Видите?

И наконец, используя отражение, Hibernate может инстанцировать класс через его no-arg конструктор. Поэтому при вызове

Person person = (Person) session.get(Person.class, <IDENTIFIER>);

Hibernate инстанцирует ваш объект Person следующим образом

Person.class.newInstance();

Что согласно документации API

Класс инстанцируется как бы выражением new с пустым списком аргументов

Мораль истории

Person.class.newInstance();

похожа на

new Person();

Nothing else

33
ответ дан 24 November 2019 в 06:40
поделиться

Фактически, вы можете создавать экземпляры классов, у которых нет конструктора с 0 аргументами; вы можете получить список конструкторов класса, выбрать один и вызвать его с фиктивными параметрами.

Хотя это возможно, и я думаю, это сработает и не вызовет проблем, согласитесь, что это довольно странно.

Создание объектов так, как это делает Hibernate (я считаю, что он вызывает конструктор 0-arg, а затем, вероятно, изменяет поля экземпляра напрямую через Reflection. Возможно, он знает, как вызывать сеттеры) немного противоречит тому, как объект должен быть построенным на Java - вызовите конструктор с соответствующими параметрами, чтобы новый объект был тем объектом, который вам нужен. Я считаю, что создание экземпляра объекта с последующим его изменением - это своего рода «анти-Java» (или, я бы сказал, анти-чисто теоретическая Java) - и определенно, если вы сделаете это с помощью прямых манипуляций с полями, это будет инкапсуляция и все эти причудливые инкапсуляционные штуки. .

Я думаю, что правильным способом сделать это было бы определение в отображении Hibernate, как объект должен быть создан из информации в строке базы данных с использованием подходящего конструктора ... но это было бы более сложным - то есть как Hibernate. было бы еще сложнее, отображение было бы сложнее ... и все было бы более "чистым"; и я не думаю, что это будет иметь преимущество перед текущим подходом (кроме того, что вы чувствуете себя хорошо, когда делаете что-то «должным образом»).

Сказав это и учитывая, что подход Hibernate не очень "чистый", обязательство иметь конструктор с 0 аргументами не является строго необходимым, но я могу частично понять требование, хотя я считаю, что они сделали это чисто основания "надлежащего пути", когда они отклонились от "правильного пути" (хотя и по разумным причинам) задолго до этого.

6
ответ дан 24 November 2019 в 06:40
поделиться

Гораздо проще создать объект с конструктором без параметров через отражение, а затем заполнить его свойства данными через отражение, чем пытаться подобрать данные к произвольным параметрам параметризованного конструктора, с меняющимися именами/конфликтами именования, неопределенной логикой внутри конструктора, наборами параметров, не соответствующими свойствам объекта, и так далее.

Многие ORM и сериализаторы требуют использования конструкторов без параметров, потому что параметризованные конструкторы через отражение очень хрупки, а конструкторы без параметров обеспечивают стабильность приложения и контроль над поведением объекта для разработчика.

2
ответ дан 24 November 2019 в 06:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: