From: Lew on 10 Feb 2010 17:26 Mike Schilling wrote: > Tom Anderson wrote: >> On Wed, 10 Feb 2010, Mike Schilling wrote: >> >>> Tom Anderson wrote: >>>> new SeparatedString("foo=bar", '=') >>>> >>>> is equivalent to: >>>> >>>> new StringPair("foo", "bar) >>>> */ >>>> class SeparatedString { >>>> public SeparatedString(String str, char separator) { >>>> // now what? >>> this(split(str, separator)); >>> } >>> } >>> private String[] split(String str, char separator) >>> { >>> ... >>> } >>> >>> private SeparatedString(String[] strings) >>> { >>> super(strings[0], strings[1]); >>> } >>> >>> I refuse to be concerned about the cost of the allocation of the >>> String array. >> Okay. So now: >> >> /** A string pair combining a search term, and the string resulting >> from using the term as the parameter to the supplied query. >> */ >> class TermAndResult extends StringPair { >> public KeyAndValueString(String term, PreparedStatement query) { >> // and no, it's not Derby or H2 >> } >> } >> >> Believe me, i can keep contriving examples all week! > > The same thing, but make "split" talk to the DBMS, and probably thow some > interesting exceptions. Believe us, all those examples you contrive can be handled with existing Java semantics. Since by definition what you put in there cannot rely on the instance being constructed, it must be available through a static method call. Or if not, you can make a factory to create the instance with whatever you need. A typical pattern is to use a builder in the factory method that starts with a no-arg constructor, probably 'private', and the setting of necessary properties to create a viable state. None of this is about what Java cannot do, since it can, but about how you wish it would do it, which is tough noogies for you. -- Lew
From: Mike Schilling on 10 Feb 2010 17:54 Lew wrote: > > Believe us, all those examples you contrive can be handled with > existing Java semantics. Since by definition what you put in there > cannot rely on the instance being constructed, it must be available > through a static method call. > Or if not, you can make a factory to create the instance with > whatever you need. A typical pattern is to use a builder in the > factory method that starts with a no-arg constructor, probably > 'private', and the setting of necessary properties to create a viable > state. > None of this is about what Java cannot do, since it can, but about > how you wish it would do it, which is tough noogies for you. The part of it I would find annoying (if I thought it existed) would be if some sorts of initialization could only be done via a factory. A large part of designing a class is determining what interface it shows to client code. If the result includes a constructor rather than a factory, changes to the class's implementation shouldn't force a reversal of that decision.
From: rossum on 10 Feb 2010 17:58 On Tue, 09 Feb 2010 16:22:35 +0000, Steven Simpson <ss(a)domain.invalid> wrote: >Eric Sosman wrote: >> On 2/9/2010 4:49 AM, Pitch wrote: >>> Also, you cannot place any code before super(...) which I already new, >>> and it also sucks. :) >> [...] >>> Anyone knows why is that so? >> [...] 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. > >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(). Static initialisation code in the derived class is run before super() in the constructor. rossum public class Main { public static void main(String[] args) { Derived dd = new Derived(); System.out.println("Done."); } // end main() } // end class Main class Base { public Base() { System.out.println("Base constructor."); } } // end class Base class Derived extends Base { static { System.out.println("Derived static code."); } { System.out.println("Derived initialisation code."); } public Derived() { super(); System.out.println("Derived constructor."); } } // end class Derived **** Output **** run: Derived static code. Base constructor. Derived code. Derived constructor. Done.
From: Tom Anderson on 10 Feb 2010 18:07 On Wed, 10 Feb 2010, Lew wrote: > Mike Schilling wrote: >> Tom Anderson wrote: >>> On Wed, 10 Feb 2010, Mike Schilling wrote: >>> >>>> Tom Anderson wrote: >>>>> new SeparatedString("foo=bar", '=') >>>>> >>>>> is equivalent to: >>>>> >>>>> new StringPair("foo", "bar) >>>>> */ >>>>> class SeparatedString { >>>>> public SeparatedString(String str, char separator) { >>>>> // now what? >>>> this(split(str, separator)); >>>> } >>>> } >>>> private String[] split(String str, char separator) >>>> { >>>> ... >>>> } >>>> >>>> private SeparatedString(String[] strings) >>>> { >>>> super(strings[0], strings[1]); >>>> } >>>> >>>> I refuse to be concerned about the cost of the allocation of the >>>> String array. >>> Okay. So now: >>> >>> /** A string pair combining a search term, and the string resulting >>> from using the term as the parameter to the supplied query. >>> */ >>> class TermAndResult extends StringPair { >>> public KeyAndValueString(String term, PreparedStatement query) { >>> // and no, it's not Derby or H2 >>> } >>> } >>> >>> Believe me, i can keep contriving examples all week! >> >> The same thing, but make "split" talk to the DBMS, and probably thow some >> interesting exceptions. Ugh, you're right. Sorry, not thinking terribly clearly there. > Believe us, all those examples you contrive can be handled with existing > Java semantics. Since by definition what you put in there cannot rely > on the instance being constructed, it must be available through a static > method call. I'm not claming it can't be done. My point is that this pointless rule forces ugly and in some cases actually inefficient workarounds. The problem is the rule. The solution is to change it. tom -- Big Bang. No god. Fadeout. End. -- Stephen Baxter
From: Lew on 10 Feb 2010 18:46
rossum wrote: > Static initialisation code in the derived class is run before super() > in the constructor. > > public class Main { > > public static void main(String[] args) { > > Derived dd = new Derived(); > > System.out.println("Done."); > } // end main() > > } // end class Main > > > class Base { > > public Base() { > System.out.println("Base constructor."); > } > > } // end class Base > > > class Derived extends Base { > > static { System.out.println("Derived static code."); } > > { System.out.println("Derived initialisation code."); } > > public Derived() { > super(); > System.out.println("Derived constructor."); > } > } // end class Derived > > **** Output **** > > run: > Derived static code. > Base constructor. > Derived code. Since I don't see that string in your example, I'm guessing you meant to put Derived initialisation code. The 'println()' call for which is actually part of the constructor, btw. > Derived constructor. > Done. I don't see "Done." in your example code either. -- Lew |