Re: Do some computation before calling super constructor.



Hendrik Maryns wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
NotDashEscaped: You need GnuPG to verify this message

Hi,

I know it?s a common problem, but I still have no nice solution for it:
I want to do some computation in my constructor before invoking the
super(String name) constructor, specifically, I need to build the string
that is given as an argument to it, based on the arguments I get for
this constructor. I just read about the Layered Initialisation pattern,
which could be used for this, but that would definitely be overkill. I
can get around this by invoking the standard constructor and making a
protected setName() method, but that is ugly, and it means I can?t
declare name final.

So different questions:
- is there a preferred trick for this?
- does it indicate I am making a design error?

You can stop reading and answer now if you are in a hurry...

Concrete: I have a class State, which represents a state in an
automaton. (Note that it is not used in the State pattern, because the
automata are way too big for that, and the transition rules are
generated at runtime.) Now for some manipulations of automata, I have
to build a new one, which has sets of states of the original one as its
states. So being clever, I thought: let?s subclass State with a class
called StateSet, which maintains a set of states. (This probably isn?t
the best solution in regard of wasted memory, but I want to keep most
automata in a hashmap anyway, efficiency concerns are for later.)

As those states have a name, I want to give the StateSets names like
{state1, state2, ... }, you know, standard mathematical notation. But
it is impossible to build this string in the constructor. So I got the
solution below:

public class StateSet extends State {

public StateSet(Set<State> states) {
// I would like to build the name first, then call the other
// constructor, but Java won't let me...
StringBuilder name = new StringBuilder("{");
for (State state : states) {
name.append(state).append(',');
}
// get rid of trailing comma
name.deleteCharAt(name.length()-1);
setName(name.toString());
// super(name.toString()) ==> not allowed
this.states.addAll(states);

}

// other methods, instance variable HashSet<State> states, ...

}

public class State {

public State(String name) {
super();
this.name = name;
}

private String name;

protected void setName(String name) {
this.name = name;
}

// other methods, such as getName()

}

Many thanks, H.
In a constructor, the super call MUST be the first line of your code.
Therefore, you cannot call super after having made some computations.
What you can do in State :

public class State {
public State(){
}
public State(String name) {
super();
init(name);
}
protected void init(String name) {
this.name = name;
}
private String name;

protected void setName(String name) {
this.name = name;
}

// other methods, such as getName()

}

and in StateSet :
public class StateSet extends State {

public StateSet(Set<State> states) {
StringBuilder name = new StringBuilder("{");
for (State state : states) {
name.append(state).append(',');
}
// get rid of trailing comma
name.deleteCharAt(name.length()-1);
setName(name.toString());
init(name.toString());
this.states.addAll(states);

}

// other methods, instance variable HashSet<State> states, ...

}
.



Relevant Pages

  • Do some computation before calling super constructor.
    ... I want to do some computation in my constructor before invoking the ... I have a class State, which represents a state in an ... Now for some manipulations of automata, ... public class StateSet extends State { ...
    (comp.lang.java.help)
  • Re: what is the RIGHT THING to make a constructor of a subclass, using super()
    ... If you are left with that requirement as a necessary or desirable part of the design, then the usual approach is probably to write a static method in the class that you call as an argument to the call to superfrom your constructor. ... public class TestDerived extends TestBase ... public Customer(String firstName, String lastName) { ... public class SlashSeparatedCustomer extends Customer { ...
    (comp.lang.java.programmer)
  • Re: getting used to Java - question about "style"
    ... > "Subclasses may override nonfinal methods and Java will dispatch a call to ... > before executing the derived class constructors. ... > constructor." ... public class B extends A ...
    (comp.lang.java.programmer)
  • Re: constructor
    ... constructor, x will be initialized two times. ... public class Class ... > FIeld initializers run before the base class cstructor runs, the construcor body rus after hte base class constructor runs ... > public class test ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Real simple Class question-Newbe
    ... Look up Constructor. ... >public class testParseString ... >public string InputString ...
    (microsoft.public.dotnet.languages.csharp)

Loading