Re: Do some computation before calling super constructor.
- From: Fabien Bergeret <fabien.bergeret@xxxxxxxxxxxxxxxxxxxxxx>
- Date: Wed, 08 Feb 2006 16:12:42 +0100
Hendrik Maryns wrote:
-----BEGIN PGP SIGNED MESSAGE-----In a constructor, the super call MUST be the first line of your code.
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.
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, ...
}
.
- Follow-Ups:
- Re: Do some computation before calling super constructor.
- From: Oliver Wong
- Re: Do some computation before calling super constructor.
- References:
- Do some computation before calling super constructor.
- From: Hendrik Maryns
- Do some computation before calling super constructor.
- Prev by Date: Do some computation before calling super constructor.
- Next by Date: Run an application in a html document
- Previous by thread: Do some computation before calling super constructor.
- Next by thread: Re: Do some computation before calling super constructor.
- Index(es):
Relevant Pages
|
Loading