Loosen Constructor super()/this() call restrictions
Jeremy Manson
jeremy.manson at gmail.com
Sun Mar 22 18:07:56 PDT 2009
Also, you probably need to state that super will now be inserted as
the first thing that happens in a constructor only when static
analysis determines that there are no calls to super() or this() in
the code.
One of the benefits of super() being the first thing called in a
constructor was that a subclass could never see a partially
initialized version of its super-class stuff. With that in mind, what
are the new semantics like?
For example, now that this() and super() can come in the middle of a
constructor, are the semantics implicitly changed so that you can
catch exceptions thrown by this() and super()? Does that mean that
objects can now be seen as partially initialized in sub-constructors?
In the same vein, is there any desire to prevent code from accessing
fields / methods of superclasses before super() is invoked?
Jeremy
On Sun, Mar 22, 2009 at 5:49 PM, Jeremy Manson <jeremy.manson at gmail.com> wrote:
> It seems to me that you might need more semantics. For example, the
> specification should probably work with the definite assignment rules
> to make sure that the calls to super / this, if present, both
> definitely happen and only happen exactly once per constructor. Here
> are a couple of constructors for class Foo that should probably result
> in compilation errors:
>
> Foo() {
> if (something) {
> super(blah)
> }
> }
> Foo() {
> super(blah);
> super(blah);
> }
>
> Also, it seems to me that you would want to be careful about access to
> fields of the parent object before the invocation of super().
>
> Jeremy
>
> On Sun, Mar 22, 2009 at 3:55 PM, Mike Duigou <Mike.Duigou at sun.com> wrote:
>> AUTHOR(S): Mike Duigou
>>
>> OVERVIEW
>>
>> FEATURE SUMMARY: Currently, if present, a call to another
>> constructer via super() or this() must be the first statement of a
>> constructor. This proposal would loosen the restrictions on calls to
>> super() and this () to allow local variable declaration and several
>> types of statements to appear before the call to super() or this().
>>
>> MAJOR ADVANTAGE: This proposal is most useful when the
>> constructor parameters must be mutated before calling the other
>> super() or this() constructor.
>>
>> MAJOR BENEFIT: This proposal may allow for simpler, easier to
>> understand constructions in the calling of super() and this()
>> constructors. It also eliminates the need for some static factory
>> methods which are currently used to work around this problem. The
>> resulting code is more uniform in the use of constructors to create
>> objects.
>>
>> MAJOR DISADVANTAGE: This is a change to the Java language grammar
>> and will require changes to compilers, static analysis tools and any
>> other uses that parse Java source code.
>>
>> ALTERNATIVES: The common alternatives when the input parameters
>> cannot be easily mutated into the required parameters for calling
>> another constructor are to provide a static factory method that does
>> the work instead of a constructor. Private varargs constructors that
>> understand a specific order of parameters passed are also used.
>>
>> EXAMPLES
>>
>> Show us the code!
>>
>> SIMPLE EXAMPLE:
>>
>> /**
>> * presents a measurement in fractional inches.
>> */
>> public class Inches {
>> private final int numerator;
>>
>> private final int denominator;
>>
>> public Inches( int numerator, int denominator ) {
>> this.numerator = numerator;
>> this.denominator = denominator;
>> }
>>
>> public Inches( int whole, int numerator, int denominator ) {
>> // simple this() call
>> this( whole * denominator + numerator, denominator );
>> }
>>
>> /**
>> * A private constructor for the unpleasant technique of
>> using var args to pass
>> * constructor parameters.
>> */
>> private Inches( int ... params ) {
>> this(params[0], params[1]);
>> }
>>
>> /**
>> * Makes use of a static method to transform decimal into
>> numerator and denominator
>> * which are then passed to the private varargs constructor.
>> */
>> public Inches( float decimal ) {
>> this(convert(decimal));
>> }
>>
>> /**
>> * produces a length 2 int array with the numerator at index 0 and
>> the
>> * denominator at index 1
>> */
>> private static int[] convert(float decimal) {
>> int[] result = new int[2]; // [0] numerator, [1] denominator
>>
>> // ... conversion happens here ...
>>
>> return result;
>> }
>>
>> /**
>> * Static factory method which does the conversion and returns
>> * a new Inch object
>> */
>> public static Inches toInches(double) {
>> int dec_numerator;
>> int dec_denominator;
>>
>> // ... conversion happens here ...
>>
>> return new Inches( dec_numerator, dec_denominator );
>> }
>>
>> /**
>> * Converts a decimal fraction measurement in inches to
>> it's closest fractional representation.
>> * Note : accuracy is limited to 1/1024th.
>> */
>> public Inches( double decimal ) {
>> int dec_numerator; // not allowed by Java 6 grammar
>> int dec_denominator;
>>
>> if( Math.abs(decimal) < (1.0 / 1024) ) {
>> dec_numerator = 0;
>> dec_denominator = 1;
>> } else {
>> // ... conversion happens here ...
>> }
>>
>> this( dec_numerator, dec_denominator );
>> }
>>
>> The Inches(double decimal) constructor demonstrates the new
>> grammar by declaring local variables and performing calculations upon
>> the input parameter before calling another constructor via this().
>> This example is important because the conversion from a decimal
>> fraction to a numerator and denominator produces two results from one
>> input.
>>
>> DETAILS
>>
>> SPECIFICATION: The grammar is extended to allow declaration of
>> local variables and statements involving only local variables,
>> parameters, static fields and static methods to occur before the
>> super() or this() constructor is called.
>>
>> COMPILATION: Unknown impact.
>>
>> TESTING: No special testing requirements are required for this
>> extension. Simple unit tests should be able to exercise all of
>> the required behaviour.
>>
>> LIBRARY SUPPORT: None.
>>
>> REFLECTIVE APIS: Calling constructors via reflection as an
>> alternative to explicit calls to this() or super() constructors is not
>> currently supported and this change does not impact that.
>>
>> OTHER CHANGES: No changes are likely needed to JNI, Javadoc or
>> JPDA.
>>
>> MIGRATION: Most source changes to use this feature would be
>> manually performed as they likely entail the introduction of new local
>> variables to hold intermediate results before super() or this() is
>> called. New constructors could be provided to take the place of static
>> factory methods and the methods deprecated and replaced with one
>> statement bodies consisting of "return new Foo()" with matching params
>> to their own.
>>
>> COMPATIBILITY
>>
>> BREAKING CHANGES: I believe this change is 100% backwards
>> compatible for source code as it does not restrict or change the
>> meaning of any existing statements.
>>
>> EXISTING PROGRAMS: As all of the changes are captured within the
>> constructor method it is unlikely existing programs would be
>> impacted by this change.
>>
>> REFERENCES
>>
>> EXISTING BUGS: None known.
>>
>> URL FOR PROTOTYPE (optional): None available.
>>
>>
>>
>
More information about the coin-dev
mailing list