Loosen Constructor super()/this() call restrictions (original) (raw)

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 decnumerator;  int decdenominator;  // ... conversion happens here ...  return new Inches( decnumerator, decdenominator );  }  /** *  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 decnumerator;       // not allowed by Java 6 grammar  int decdenominator;  if( Math.abs(decimal) < (1.0 / 1024) ) {  decnumerator = 0;  decdenominator = 1;  } else {  // ... conversion happens here ...  }  this( decnumerator, decdenominator );  } 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