From: Markus Eberle on 9 Feb 2010 12:49 Am 09.02.2010 18:23, schrieb Volker Borchert: > Mike Schilling wrote: >> You can accomplish this in a roundabout way by calling a static method in >> the arguments to "super()" > > Maybe so, but the most interesting thing to "do" before super() would > be try{ ..., to catch, possibly log, wrap and rethrow exceptions thrown > by the super ctor Catching an exception of the super constructor seems to be unwise, as the object is then in an undefined state. Cheers, Markus
From: Patricia Shanahan on 9 Feb 2010 13:12 Markus Eberle wrote: > Am 09.02.2010 18:23, schrieb Volker Borchert: >> Mike Schilling wrote: >>> You can accomplish this in a roundabout way by calling a static >>> method in >>> the arguments to "super()" >> >> Maybe so, but the most interesting thing to "do" before super() would >> be try{ ..., to catch, possibly log, wrap and rethrow exceptions thrown >> by the super ctor > > Catching an exception of the super constructor seems to be unwise, as > the object is then in an undefined state. That is why one should "possibly log, wrap and rethrow" the exception, not ignore it. There are several inconveniences associated with constructors, including this one, that can be avoided by using private constructors that are only called from static factory methods. Patricia
From: markspace on 9 Feb 2010 13:15 Markus Eberle wrote: > Am 09.02.2010 18:23, schrieb Volker Borchert: >> Mike Schilling wrote: >>> You can accomplish this in a roundabout way by calling a static >>> method in >>> the arguments to "super()" >> >> Maybe so, but the most interesting thing to "do" before super() would >> be try{ ..., to catch, possibly log, wrap and rethrow exceptions thrown >> by the super ctor > > Catching an exception of the super constructor seems to be unwise, as > the object is then in an undefined state. I'm sure logging an exception and then throwing another exception (or rethrowing the original) would be fine. I agree that anything else--logging and ignoring, or logging and returning immediately without throwing--would be inviting disaster.
From: Eric Sosman on 9 Feb 2010 13:48 On 2/9/2010 11:39 AM, Lew wrote: > Eric Sosman wrote: >>>> [...] If it were possible to >>>> run arbitrary code on a Sub instance before its Super-ness had >>>> been established and its Super invariants put in place, you'd >>>> be working with a Sub that was a Super in name only, but not in >>>> actuality. > > Steven Simpson wrote: >>> Could that restriction not be loosened in a compiler-verifiable way, >>> i.e. check that no statement prior to super() uses 'this' (explicitly >>> or implicitly)? Therefore, there would be no arbitrary code acting >>> on the Sub instance, until after super(). > > Mike Schilling wrote: >> You can accomplish this in a roundabout way by calling a static method >> in the arguments to "super()" > > The method doesn't have to be static. The advantage of a static method > is that the compiler will complain if you refer to instance members, > thus preventing you from relying on incompletely-constructed elements. Are you sure the method can be non-static? Maybe you're doing something tricky that I haven't thought of, but when I try the obvious thing class Super { Super(int value) { System.out.println(value + " is super!"); } } class Sub extends Super { Sub() { super(makeValue()); } private /* static */ int makeValue() { return 42; } } .... the compiler complains "cannot reference this before supertype constructor has been called" at the point of the method call. -- Eric Sosman esosman(a)ieee-dot-org.invalid
From: Mike Schilling on 9 Feb 2010 13:53
Lew wrote: > Eric Sosman wrote: >>>> [...] If it were possible to >>>> run arbitrary code on a Sub instance before its Super-ness had >>>> been established and its Super invariants put in place, you'd >>>> be working with a Sub that was a Super in name only, but not in >>>> actuality. > > Steven Simpson wrote: >>> Could that restriction not be loosened in a compiler-verifiable way, >>> i.e. check that no statement prior to super() uses 'this' >>> (explicitly or implicitly)? Therefore, there would be no arbitrary >>> code acting on the Sub instance, until after super(). > > Mike Schilling wrote: >> You can accomplish this in a roundabout way by calling a static >> method in the arguments to "super()" > > The method doesn't have to be static. It does: import java.io.*; class Test extends FilterInputStream { Test() throws Exception { super(getStream()); } InputStream getStream() throws Exception { return new FileInputStream("foo.txt"); } } % javac -g Test.java Test.java:7: cannot reference this before supertype constructor has been called super(getStream()); ^ 1 error |