<div dir="ltr"><div>Hi folks,</div><div><br></div><div>I'm working on this issue:</div><div><br></div><div style="margin-left:40px"><a href="https://bugs.openjdk.org/browse/JDK-8194743" target="_blank">JDK-8194743</a> - Permit additional statements before this/super in constructors.</div><div><br></div><div>Obviously this change requires a JEP, and so we have this JEP draft for review:</div><div><br></div><div style="margin-left:40px"><a href="https://bugs.openjdk.org/browse/JDK-8300786" target="_blank">JDK-8300786</a> - No longer require super() and this() to appear first in a constructor</div><div><br></div><div>Here's a summary of the discussion that's occurred so far on amber-dev...</div><div><br></div><div>People are agreeable with the general idea of relaxing the JLS rules here, but of course the devil is in the details.<br></div><div><br></div><div>The current JMVS gives constructors a lot more flexibility wrt. superclass initialization than the JLS:</div><div><ul><li>Multiple invocations of <code>this()</code> and/or <code>super()</code> may appear in a constructor, as long as on any code path there is exactly one invocation</li><li>Arbitrary code may appear before <code>this()</code>/<code>super()</code>, as long as that code doesn't reference the instance under construction, with an exception carved out for field assignments<br></li><li>However, invocations of <code>this()</code>/<code>super()</code> may not appear within a <code>try { }</code> block (i.e., within a bytecode exception range)</li></ul></div><div>So the question becomes, how far to push the JLS up against these limits, or conceivably even past them (i.e., relaxing both the JLS and JVMS).</div><div><br></div><div>Roughly in order of increasing aggressiveness, here are some of the options that have been discussed (these are not all mutually exclusive):<br></div><div><ol><li>Permit "static context" code prior to <span style="font-family:monospace">super()</span>/<span style="font-family:monospace">this()</span>, but otherwise <span style="font-family:monospace">super()</span>/<span style="font-family:monospace">this()</span> still must occur exactly once and as a top-level statement in the constructor.</li><li>Allow arbitrary appearances of <span style="font-family:monospace">super()</span>/<span style="font-family:monospace">this()</span> in constructors, and apply DA/DU analysis like a blank final field to verify exactly one ever gets invoked</li><li>Also allow assignments to fields declared in the same class prior to <span style="font-family:monospace">super()</span>/<span style="font-family:monospace">this()</span></li><li>(JVMS mod required) Allow super()/this() within try { } blocks, as long as within any catch block execution completes abruptly with another throw<br></li></ol></div><div>#1 is the minimal change. It accomplishes the basic goal of allowing "housekeeping" prior to superclass initialization. It also requires fairly minimal JLS changes (drafted already in the JEP).<br></div><div><br></div><div>#2 is arguably a more natural way to relax things, but beyond #1 it addresses a fairly niche set of incremental use cases, and would have a large impact on the JLS for that relatively meager marginal return.</div><div><br></div><div>#3 is debatable. The 'this' escape problem (e.g., <span style="font-family:monospace">HashSet(Collection)</span>) is very real and Java provides victim subclasses with no easy way to avoid it. This feature would make it easy to avoid. However, it has a conceptual cost. Allowing field assignments, but no other 'this' references, is an obvious hack/exception to the rules. To be sure, there are practical reasons for it (which is why it was added to the JVMS in the first place), but from a language design point of view it left some people a little uneasy. It's a classic beauty vs. function debate.<br></div><div><br></div><div>#4 is kind of a related side issue that came up. It could stand alone as an independent change. I'd be curious to hear people's opinions here. It would allow you to catch exceptions thrown by a <span style="font-family:monospace">super()</span>/<span style="font-family:monospace">this()</span> call as long as you then (re)throw some exception. It would also fix a difficulty for bytecode weaving tools that do things like measure method execution times.<br></div><div><br></div><div><div>One could also argue that by making <span style="font-family:monospace">super()</span>/<span style="font-family:monospace">this()</span> calls more like normal method calls (less "special"), items #2 and #4 would improve language harmony, etc.</div><div><br></div><div><div>In any case, the current JEP draft takes the conservative route and opts for #1 only.</div><div><br></div><div>Thanks,<br></div><div>-Archie</div><br><div>-- <br><div dir="ltr">Archie L. Cobbs</div></div></div></div></div>