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