From: Lew on
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
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
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
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
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