Давайте посмотрим на эту проблему. Прежде всего, что происходит, когда вы вызываете new MyClass("foo");
? Ну, есть две вещи. Прежде всего, виртуальная машина будет выделять память, необходимую для хранения объекта типа MyClass
. Затем вызывается конструктор. Задача конструктора - инициализировать эту только что выделенную память. Поэтому конструктор не имеет типа возврата вообще (даже не пусто). Значение, возвращаемое новым оператором, является ссылкой на выделенную память, поэтому конструктор также не может вернуться.
Тогда, что было бы полезно для вызова рекурсивного конструктора. Единственное преимущество такого вызова было бы в том, чтобы обрабатывать определенные параметры конструктора, такие как другие, и делать это путем повторного вызова конструктора. Хотя это возможно, обычно легко просто настроить значения в самом конструкторе (используя не конечные параметры), а после этого инициализировать атрибуты объекта (короче, для этого вам не нужна рекурсия).
Во-вторых, вы можете сделать рекурсию довольно легко, разгрузив всю работу на рабочий метод, который может рекурсировать столько, сколько вы хотите.
Более интересным вопросом является ограничение на супер или этот вызов, являющийся первым оператором конструктора. Это ограничение, вероятно, было включено, чтобы препятствовать неаккуратным или небезопасным методам программирования. Заявление здесь выделено жирным шрифтом, хотя возможно (хотя и не красиво) обойти это ограничение. Если вы помните, что выражения могут иметь побочные эффекты (например, назначения переменных), а выражения, используемые для параметров, вызывают перед самим вызовом, можно создать сложные выражения, которые выполняют все ваши вычисления, прежде чем вызывать конструктор делегата.
Общая причина, по которой вы хотите иметь вызов делегата/супер-конструктора позже в теле конструктора, - это манипуляция параметрами. Вы можете сделать это с помощью (статических) вспомогательных функций, которые выполняют эти вычисления и обеспечивают правильные значения. Обычно это чище, но не во всех случаях. Фактическая скорость выполнения не должна быть затронута, так как точка доступа может очень хорошо подстроить эти вещи.
Это означает, что в конечном итоге рассмотрение сводится к обеспечению гибкости бесплатного размещения делегатов/супер-вызовов в сравнении с дополнительной безопасностью, обеспечиваемой путем принятия неправильных методов намного сложнее. Выбор, сделанный дизайнерами Java (и общей философией Java), заключается в том, чтобы сделать его сложнее делать неправильные вещи ценой необработанной языковой власти у экспертов (с повышенной сложностью). Выбор сделан для меня действительным, хотя я лично хотел бы силы (всегда можно реализовать Java-язык Java на JVM, который не имеет этих ограничений).
Несомненно, конструктор - это метод, который возвращает новый экземпляр создаваемого класса, а не null? – Finbarr
@ Finbarr Нет, это был бы заводский метод; сам конструктор не имеет возвращаемого значения. –
@Finbarr - никто не упомянул 'null'! Конструкторы, строго говоря, не то же самое, что и другие методы, поэтому нет смысла точно описывать их как имеющие тип возврата вообще. Тело конструктора ничего не возвращает, и когда один конструктор вызывает другого, промежуточное возвращаемое значение отсутствует, поэтому ближайшая аналогия имеет метод, который возвращает 'void'. –