Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!aioe.org!eternal-september.org!feeder.eternal-september.org!.POSTED!not-for-mail From: Eric Sosman Newsgroups: comp.lang.java.programmer Subject: Re: Automatic linking of related objects in constructor Date: Wed, 29 Jun 2011 08:29:00 -0400 Organization: A noiseless patient Spider Lines: 68 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Injection-Date: Wed, 29 Jun 2011 12:29:33 +0000 (UTC) Injection-Info: mx04.eternal-september.org; posting-host="BrOwaJANne849xlH+KPYjQ"; logging-data="2262"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/fyrYxxaW9PUWmfYn3X5wO" User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.18) Gecko/20110616 Thunderbird/3.1.11 In-Reply-To: Cancel-Lock: sha1:2WqiLgGFalK24X5MD5EN9g/sPc0= Xref: x330-a1.tempe.blueboxinc.net comp.lang.java.programmer:5773 On 6/29/2011 5:56 AM, Qu0ll wrote: > Suppose you have class A which contains a list of objects of class B and > that the constructor for B takes in a reference to the A object which is > to include it in said list. Is it safe to make a call to A's method > addB(B b) in that B constructor passing in "this"? I have heard that > it's bad practice to "leak" a reference to an object from within its own > constructor because it may be in an invalid state. I guess you mean class B { public B(A a) { ... a.addB(this); } ... } It's not a wonderful idea, but even if it's not safe it looks sort of safe-ish, right? Ah, but code changes, and lo! one of the changes introduces a subclass: class C extends B { public C(A a) { super(a); ... } } Okay, still not *too* bad -- or is it? Let's expand that last set of ellipses: class C extends B { public C(A a) { super(a); if (phaseOfTheMoon() != Moon.FULL) throw new IllegalStateException(); ... } } Yikes! Now if C's constructor throws up, the A instance is left holding a reference to something that appears to be a C in B's clothing, but is in fact nothing sensible at all! > If not, how else can I automatically add the B object to the list in A > without forcing the client programmer to explicitly call addB() given > that they have already passed in the B as an argument? (I assume you meant "A as an argument.") Consider using a factory method: class B { private B(A a) { // so clients can't do "new B(a)" ... } public static B instanceOf(A a) { B b = new B(a); // B's constructor is now completely finished a.addB(b); return b; } } -- Eric Sosman esosman@ieee-dot-org.invalid