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