Защо се нуждаем от конструктор без аргументи по подразбиране в Java?

Защо се нуждаем от конструктор без аргументи по подразбиране в много API, свързани с Java? Като общо правило, всички класове на Java bean или класове на обекти (JPA и т.н.) или класове за внедряване на JAX-WS изискват изричен конструктор без аргументи.

Ако по подразбиране Java предоставя конструктор без аргументи, тогава защо повечето от тези стандарти изискват изричен конструктор?


person RRR_J    schedule 20.06.2010    source източник


Отговори (6)


Java предоставя само конструктор без аргументи по подразбиране, ако не са дефинирани други конструктори. По този начин, ако имате други конструктори, трябва сами изрично да дефинирате конструктор без аргументи.

Тези рамки използват API за отражение и разглеждат имената на методите, за да определят как да задават свойства. Аргументите на конструктора могат да бъдат намерени само по тип, а не по име, така че няма начин рамката надеждно да съпостави свойствата с аргументите на конструктора. Следователно те изискват конструктор без аргументи, за да създадат обекта, след което могат да използват методите за настройка, за да инициализират данните.

Някои рамки може да поддържат @ConstructorProperties като алтернатива .

person OrangeDog    schedule 20.12.2010

Вярвам, че рамки, които изискват public нулеви конструктори, го правят, защото използват отражение за инстанциране на типове, напр. чрез Class.newInstance().

Що се отнася до това защо конструкторът по подразбиране може да не работи в този случай, ето съответния JLS раздел:

Конструктор по подразбиране JLS 8.8.9

Ако class не съдържа декларации на конструктор, тогава автоматично се предоставя конструктор по подразбиране, който не приема параметри:

  • ако class е декларирано public, тогава на конструктора по подразбиране имплицитно се дава модификаторът за достъп public;
  • ако класът е деклариран protected, тогава на конструктора по подразбиране имплицитно се дава модификаторът за достъп protected;
  • ако класът е деклариран private, тогава на конструктора по подразбиране имплицитно се дава модификаторът за достъп private;
  • в противен случай конструкторът по подразбиране има достъп по подразбиране, подразбиращ се от модификатор за достъп.

Така че в public клас, конструкторът по подразбиране ще има правилната видимост, но в противен случай трябва да бъде предоставен изрично public такъв.

person polygenelubricants    schedule 20.06.2010
comment
Видимостта не е проблем, тъй като може да се заобиколи с API за отражение. - person OrangeDog; 21.12.2012
comment
и какво ще кажете за извикването на super() в конструктора по подразбиране, играе ли роля тук? - person Macilias; 11.08.2015

Необходим е конструктор за инициализиране на всички стойности, които не са по подразбиране, и може да съдържа странични ефекти, които са необходими.

Ако имате стил на програмиране, който насърчава минимален конструктор за обекти за прехвърляне на данни, това би изглеждало ненужно, но библиотеките са избрали да не приемат никакъв стил на програмиране за конструкторите.

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

person Peter Lawrey    schedule 20.06.2010

Java предоставя само конструктор без аргументи, ако не е приложен друг конструктор. В редица Java API (напр. JPA, Serialization и много други, които изграждат обекти от външно представяне) се изисква екземпляр на обекта, преди да могат да бъдат зададени стойностите на данните на обекта, тъй като определението за това как се прилагат стойностите е дефинирани чрез членове на екземпляр на обекта (напр. readExternal(ObjectInput)). Ако даден клас има само конструктор, който приема някои аргументи, тогава може да не е възможно библиотеката да конструира екземпляр, освен ако не е дефиниран отделен конструктор без аргументи.

Струва си да се отбележи, че това е избор на дизайн от изпълнителя на конкретната библиотека, възможно е да се изгради API/Framework, който може да екстернализира и пресъздава обекти, които нямат конструктор без аргументи (дефинирането на отделен фабричен клас е един подход). Моделът за изискване на конструктор без аргументи се появи първо в Java Serialization (мисля) и беше приет като фактически стандартен подход в други библиотеки (напр. JPA). Слабостта на този подход е, че предотвратява използването на неизменни обекти.

person Michael Barker    schedule 20.06.2010
comment
XStream, например, може да сериализира обекти в XML и не изисква конструктор без аргументи. - person Mario Ortegón; 20.06.2010

Две причини: 1) да се избегне NullPointerException, ако поле с данни на екземпляр от референтен тип данни е неинициализирано. Осигуряването на явен конструктор ще ви даде възможност да инициализирате такива полета с данни, ако те не са били инициализирани, когато са декларирани 2) за потребители, които биха искали да използват конструктори без аргументи; те не се предоставят автоматично, ако съществуват други конструктори

person Nana    schedule 14.01.2014

Много от тези рамки произлизат от по-ранните идеи на "POJO" и особено JavaBeans. Най-малкият полезен Java обект по конвенция би имал конструктор без аргументи и всеки член, достъпен чрез методи като get/setProperty1 и is/setProperty1 за булеви стойности. Ако класовете следват тази конвенция на интерфейса, инструментите и рамките, използващи отражение, могат да работят „извън кутията“.

person Axel Podehl    schedule 28.03.2019