Why does this() and super() have to be the first statement in a constructor?
Howard Lovatt
howard.lovatt at gmail.com
Sun Oct 16 16:41:54 PDT 2011
I proposed this a long while ago, see email chain below. My particular
requirement was wanting a field initialised so that the super constructor
could call an instance method defined in the derived class. The example I
gave in the email below was contrived to keep it short. The actual use case
was very similar to an inner class (therefore easy to see why you would want
this because inner clas do this already).
My proposal was to allow read and write of a class's own fields (not those
in super) and local variables before super/this was called.
Would the above description be a sufficiently detailed request to start
working on a formal proposal? Is this something that is likely to get
support if a formal proposal was submitted?
Cheers,
-- Howard.
=================================================================
fromIncidentDaemon at sun.com IncidentDaemon at sun.comtohoward.lovatt@iee.org
date23 February 2006 21:37subjectYour Report (Review ID: 654094) - Alow
field inizialization before super call in constructors
hide details 23/02/2006
************************************************
Your report has been assigned an internal review ID of: 654094
This review ID is NOT visible on on Sun Developer Network (SDN).
We greatly appreciate your interest in improving the quality of Java(tm)
Technology from Sun Microsystems.
Please be aware that the large volume of reports we receive sometimes
prevents us from responding individually to each message.
We currently have a three week average response time. If the information is
determined to be a new bug, or a duplicate of a known bug, you will receive
a followup email containing a seven digit bug number. You may search for,
view, or vote for this bug on the Bug Database at http://bugs.sun.com/
.
If you just reported an issue that could have a major impact on your project
and you require a timely response, please consider purchasing one of the
support offerings at http://java.sun.com/support/index.html
.
The Sun Developer Network (http://developers.sun.com
) is a free service that Sun offers. To join, visit
http://developers.sun.com/global/join_sdn.html
.
For a limited time, SDN members can obtain fully licensed Java IDEs for web
and enterprise development. More information is at
http://developers.sun.com/prodtech/javatools/free/
.
Thank you for your help.
---------------------------------------------------------------
dateCreated: Thu Feb 23 03:37:04 MST 2006
type: rfe
cust_name: Howard Lovatt
cust_email: howard.lovatt at iee.org
jdcid: hlovatt
status: Waiting
category: java
subcategory: specification
company: Personal submission
release: 5.0
hardware: x86
OSversion: win_xp
priority: 4
synopsis: Alow field inizialization before super call in constructors
description: A DESCRIPTION OF THE REQUEST :
At present some code cannot be written using Java source code you need to
manipulate the bytecode. In particular the Java language requires that super be
the first line of a constructor. However there are times when you need to
initialize a field from arguments supplied to the constructor before calling
the constructor. So that the super constructor can call virtual methods
defined in the base class and not get errors (e.g. NullPointerException).
EG:
class Base {
Base() { System.out.println( get_int() ); }
abstract int get_int();
}
public class Derived extends Base {
Integer value;
Derived ( int value ) { this.value = value; } // NB Autoboxed
int get_int() { return value; } // NB unboxed automatically
public static void main( String[] notUsed ) { new Derived( 1 ); } //
NullPointerException!
}
The above code throws a null pointer because you can't initialize field
value before calling super (implicitly) in Derived's constructor.
The suggested solution is to allow super to appear after the initialization,
e.g. allow:
Derived( int value ) {
this.value = value;
super()
}
If super isn't explicityly mentioned then, as at present, it is assumed to
be the first line.
JUSTIFICATION :
There are plenty of examples were initializing fields is needed.
EG1 you can't manually write the equivalent of an inner class because the
field that points to the outer class needs to be initialized before the call
to super.
EG2 this problem has been recognized for C# and an MS proposed language
extension called SPEC#(
http://research.microsoft.com/projects/specsharp/papers/krml136.pdf
on page 3) is to adopt C++ style field initialization after the : following
the constructor name and before the base (super) call. EG the example above
in SPEC# would be:
Derived( int value ) : this.value( value ), base() {}
CUSTOMER SUBMITTED WORKAROUND :
The only work around I know is to manipulate the bytecode. The system I have
used is to pass normal Java through the compiler (with super before field
initialization) and then use a bytcode manipulator called Javassist to move
the call to super to after the field initialization as a post processing
operation on the class file.
workaround:
comments: (company - Personal submission , email - howard.lovatt at iee.org)
=================================================================
On 9 October 2011 13:42, Joe Darcy <joe.darcy at oracle.com> wrote:
> Ulf Zibis wrote:
> > Anyway,
> > int c = a + b;
> > doesn't affect any object field initialization.
> > It's just a local variable, which gets lost after the instance is
> instantiated.
> >
> > As workaround, you can always use a static helper method which does the
> same:
> > super(staticHelper(a, b));
> >
> > So I agree, it would reasonable, to allow some code in advance of this()
> or super().
> >
> > + 1 for your proposal, Vimil Saju.
> >
>
> This is not a proposal, it is a question!
>
> The answer to the question has already been given on the list: since
> superclass state of the object is not initialized until after the
> superclass constructor is called, the Java language requires that a call
> to a superclass constructor occur in the first statement of a subclass
> constructor in an attempt to reduce logic errors in initialization.
>
> This restriction is annoying at time, but no one has put forward a
> detailed proposal for how the requirement could be sensibility loosened
> in a way that can be standardized and tested.
>
> -Joe
>
> > -Ulf
> >
> >
> >
> > Am 08.10.2011 01:39, schrieb Daniel Yokomizo:
> >
> >> On Oct 7, 2011 1:58 PM, "Paul Benedict"<pbenedict at apache.org> wrote:
> >>
> >>> It's a compiler error because the superclass is guaranteed to be
> >>> initialized first before the subclass.
> >>>
> >> Not guaranteed by the JVM, as in anonymous inner classes.
> >>
> >>
> >>> On Fri, Oct 7, 2011 at 11:51 AM, Vimil Saju<vimilsaju at yahoo.com>
> wrote:
> >>>
> >>>> If you have subclass then java requires that this() or super has to be
> >>>>
> >> first statement in the constructor of the subclass.
> >>
> >>>> Here is an example
> >>>>
> >>>> publicclassMyClass{
> >>>> publicMyClass(intx){}
> >>>> }
> >>>>
> >>>> publicclassMySubClassextendsMyClass{
> >>>> publicMySubClass(inta,intb){
> >>>> intc =a +b;
> >>>> super(c); // COMPILE ERROR
> >>>> }
> >>>> }The above compilation error can be resolved by rewriting the code in
> >>>>
> >> the constructor as follows
> >>
> >>>> publicclassMySubClassextendsMyClass{
> >>>> publicMySubClass(inta,intb){
> >>>> super(a + b);
> >>>> }
> >>>> }Can't the Java compiler detect that in the previous code there was no
> >>>>
> >> access to the instance fields or methods and therefore allow the code to
> >> compile without any error.
> >>
> >
> >
>
>
>
--
-- Howard.
More information about the coin-dev
mailing list