Path: csiph.com!usenet.pasdenom.info!aioe.org!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Eric Sosman Newsgroups: comp.lang.java.programmer Subject: Re: Interface with implied Constructor Date: Sat, 20 Jul 2013 17:12:47 -0400 Organization: A noiseless patient Spider Lines: 114 Message-ID: References: <925adeb1-65b5-4a50-86a8-4f04784f8da0@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Injection-Date: Sat, 20 Jul 2013 21:06:42 +0000 (UTC) Injection-Info: mx05.eternal-september.org; posting-host="0d73d8cc209bff1c6395088b400d0605"; logging-data="2088"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/pSn5ZlH82vuOiFlK8HBsp" User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:17.0) Gecko/20130620 Thunderbird/17.0.7 In-Reply-To: Cancel-Lock: sha1:HTRhFT3iqx+03bZ4mrcM5yZKZMk= Xref: csiph.com comp.lang.java.programmer:24782 On 7/20/2013 3:12 PM, Martin Gregorie wrote: > On Sat, 20 Jul 2013 19:46:16 +0200, Robert Klemme wrote: > >> On 19.07.2013 23:21, Martin Gregorie wrote: >>> [...] >>> I take the opposite approach to Robert over that for one reason: that >>> the only way to report init errors in a constructor is to throw an >>> Exception, >>> which means the instance declaration often needs to go inside a >>> try/catch block which can screw up scoping. >> >> In what ways does this screw up scoping? >> > Just that I often find that I need access to the instance outside the try/ > catch block containing the constructor call and I don't much like > initialising the pointer as null. Then ... don't initialize it. Thing thing; try { thing = new Thing(); } catch (DooWopDooWopDooWopException ex) { logger.log(Level.SEVERE, "Eek!", ex); throw ex; } System.out.println(thing.getSwing()); ... This form has the advantage that the compiler will complain if the all-important `throw ex;' is forgotten, whereas initializing to null would just get you an NPE. Very occasionally there's a situation where you really do need to use the null-ness of `thing' as an indication that construction failed. In that case, I'd still suggest not initializing: Thing thing; try { thing = new Thing(); } catch (DooWopDooWopDooWopException ex) { logger.log(Level.SEVERE, "Eek!", ex); thing = null; } if (thing != null) { System.out.println(thing.getSwing()); else { System.out.println("It don't mean a thing"); } IMHO, situations like this are suggestive of a poorly-designed Thing class (which you may be forced to endure), or of a method that's trying to do too many things and might better be split up. > This is a result of my dislike of using Exceptions to signal anything > except a fatal error and may well be a hangover from writing a lot of C > in the past. A method that returns reference to a library class whose > constructor can throw an exception, e.g. Integer, but does not itself > return an exception requires this sort of structure: > > public class Altitude > { > int alt = 0; > String error = null; > > /** > * Returning a negative number indicates an invalid height. > */ > public int getHeight(String height) > { > Integer h = null; Since this initialization is useless (the variable will always be overwritten, exception or no), why even have it? > try > { > h = new Integer(height); > if (h < 0) > error = "Below MSL"; > } > catch (NumberFormatException e) > { > error = e.getMessage(); > h = new Integer(-1); > } > > return alt = h.intValue(); > } > > public boolean isValid() > { return error === null; } > > public String getError() > { return error; } > } > > This isn't a really good example because Integer provides other ways of > doing the job, but it does illustrate the sort of scoping problem I'm > talking about: that of allowing access to the Integer instance in both > parts of the try/catch block as well as from surrounding parts of the > method body. I don't see how the NumberFormatException has much to do with it: Your getHeight() method needs the `h' at the point of its return, so its scope must include the return statement. The only "scoping issue" I can see is that the try block and the catch block have their own subsidiary scopes in which `h' also needs to be (and is) visible -- but then, why aren't you worried about the scope of `height'? (Or even of `error' and `alt'?) -- Eric Sosman esosman@comcast-dot-net.invalid