Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

small java exercise

1 view
Skip to first unread message

ros

unread,
Apr 3, 2007, 5:48:43 AM4/3/07
to
Hi,

I am working on this exercise and would be thankful if you folks
comment on it.

The requirement was as follows:

Create a MovieRating class that contains a private map with rating as
the key and minimum age as the value, populate this map when the class
is instantiated. Also include a method which takes two parameters,
rating and age and checks the minimum age in the map and returns true
or false to indicate whether or not a human with the specified age is
allowed to watch a movie with the specified rating.

My attempt is pasted below. I get a compiler error that says that I
have a missing return statement in getStatus. The return statements
that I have are in the if/else block. How can I solve this issue?
Also I am not sure about the Map?

Thanks
Ros

import java.util.HashMap;
import java.util.Map;

public class MovieRating {

private Map humanMap = new HashMap();

public MovieRating(){
humanMap.put("G", 18);
humanMap.put("PG", 16);
}

public boolean getStatus(String rating, int age){

int minAge;
minAge = Integer.getInteger((String) humanMap.get("PG"));

if (age < minAge ){
return false;
}
else if (age >= minAge){
return true;
}

}

}

Ingo R. Homann

unread,
Apr 3, 2007, 6:05:41 AM4/3/07
to
Hi,

ros wrote:
> public class MovieRating {
>
> private Map humanMap = new HashMap();
>
> public MovieRating(){
> humanMap.put("G", 18);
> humanMap.put("PG", 16);
> }
>
> public boolean getStatus(String rating, int age){
>
> int minAge;
> minAge = Integer.getInteger((String) humanMap.get("PG"));
>
> if (age < minAge ){
> return false;
> }
> else if (age >= minAge){
> return true;
> }
>
> }
>
> }

Several issues. In the first step I would do it like this:

public class MovieRating {
private int g=18; // perhaps also 'static final'?
private int pg=16;// perhaps also 'static final'?
public boolean getStatus(int age) {
return age>=pg;
}
}

In the second step - I suppose that's what you want to do - you can take
into account the parameter 'rating'. After all, I think it could be
better like this (it all depands on the rest of your architecture and
your requirenments):

public class MovieRating {
private int age;
public MovieRating(int age) {
this.age=age;
}
public boolean getStatus(int age) {
return age>=this.age;
}
}

Ciao,
Ingo

vishist

unread,
Apr 3, 2007, 6:37:00 AM4/3/07
to

Ros:
You also may want to try this,

import java.util.HashMap;
import java.util.Map;

public class MovieRating {

private Map humanMap = new HashMap();
public MovieRating(){

humanMap.put("G", new Integer(18));
humanMap.put("PG", new Integer(16));
}

public boolean getStatus(String rating, int age){

Integer ratingAge = (Integer)humanMap.get(rating);
if(ratingAge != null)
{
int minAge = ratingAge.intValue();


if (age < minAge ){
return false;
}

else{
return true;
}
}
return false;
}
}

The problem with your code is that you are trying to 1. add basic data
types to map (Map takes only references to Objects) 2. the "if/else
if" conditions has no "else" condition. For the compiler, it doesn't
know whats the default return is going to be in case if/elseif fails
3. Also, you have hardcoded the rating in access function.

Once you got this working, I guess you may want to add additional
condition checks for non-null method arguments.

V.

bcr666

unread,
Apr 3, 2007, 3:51:07 PM4/3/07
to
On Apr 3, 5:37 am, "vishist" <vishi...@gmail.com> wrote:
> public boolean getStatus(String rating, int age){
>
> Integer ratingAge = (Integer)humanMap.get(rating);
> if(ratingAge != null)
> {
> int minAge = ratingAge.intValue();
> if (age < minAge ){
> return false;
> }
> else{
> return true;
> }
> }
> return false;
> }

I am a big believer in one exit point for a method, so I would do the
following

public boolean getStatus(String rating, int age) {

boolean value = false;

Integer ratingAge = (Integer)humanMap.get(rating);
if(ratingAge != null) {
int minAge = ratingAge.intValue();

value = (age >= minAge);
}

return value;
}

Patricia Shanahan

unread,
Apr 3, 2007, 5:46:51 PM4/3/07
to
bcr666 wrote:
> On Apr 3, 5:37 am, "vishist" <vishi...@gmail.com> wrote:
>> public boolean getStatus(String rating, int age){
>>
>> Integer ratingAge = (Integer)humanMap.get(rating);
>> if(ratingAge != null)
>> {
>> int minAge = ratingAge.intValue();
>> if (age < minAge ){
>> return false;
>> }
>> else{
>> return true;
>> }
>> }
>> return false;
>> }
>
> I am a big believer in one exit point for a method, so I would do the
> following

Why one exit point per method?

[I used to believe that, but most of the logical reasons I can
articulate are covered by try-finally. I'm curious about whether there
is a better reason I'm missing.]

Patricia

ros

unread,
Apr 3, 2007, 6:58:59 PM4/3/07
to

Thank you so much Vishist for the help. It makes sense.
Ros

bcr666

unread,
May 16, 2007, 8:20:43 AM5/16/07
to
On Apr 3, 4:46 pm, Patricia Shanahan <p...@acm.org> wrote:
> Why one exit point per method?
>
> [I used to believe that, but most of the logical reasons I can
> articulate are covered by try-finally. I'm curious about whether there
> is a better reason I'm missing.]
>
> Patricia

Maybe it is my opinion, but It makes it easier to debug, and it is
easier to change later on without breaking it or introducing errors.

Lew

unread,
May 16, 2007, 9:00:22 AM5/16/07
to

I disagree. The single-exit anal retention makes it harder to debug, and
harder to change later on, especially when it forces you into ridiculous
levels of nesting and extraneous conditionals, not to mention the introduction
of superfluous "retVal" variables. I'd stick with Patricia's insights; she's
one of the god(desse)s of Java.

Seriously, Patricia - you provide some of the sharpest, most succinct,
to-the-point and informative posts on the topic that there are.

Ignore her advice at your peril. (Not that she's infallible, but I have yet
to find her in error in this forum.)

--
Lew

Patricia Shanahan

unread,
May 16, 2007, 3:14:46 PM5/16/07
to

BLUSH! And thanks. However, two points:

1. In this case, I am not so much giving advice as asking for insight.
Are there advantages in Java to pushing for single exit that outweigh
the cost of making the code more complicated, for example by requiring a
"retVal"? If so, what are they?

I believe that there is a significant gain in ease of debug and change
for languages without try-finally or equivalent. I am just not convinced
for Java.

2. Even when I am giving advice, I really want anyone who is interested
in the topic and not convinced by my arguments to question and challenge
what I am saying. Maybe I'll get to learn something that way.

Patricia

Patricia Shanahan

unread,
May 16, 2007, 3:17:11 PM5/16/07
to

Can you explain why?

Thanks,

Patricia

Daniel Pitts

unread,
May 16, 2007, 4:31:47 PM5/16/07
to


if (age < minAge) isn't true, then age >= minAge MUST be true, so
after for it again doesn't make sense so what you're really trying to
do is
if (age < minAge) {
return false;
} else { // age >= minAge
return true;
}

Also, when the difference in outcome of an if/else statement is only a
boolean value, you can replace the if/else with just the boolean
value. So you end up with this:
// return true if the age is acceptable.
return age >= minAge;


Daniel Pitts

unread,
May 16, 2007, 4:35:03 PM5/16/07
to

I also find that avoiding multiple exit points leads to variable
reuse, which is a far worse practice. Actually, I think that it makes
sense for a method to possible have multiple exit points, as long as
it only has one entry point :-) Can you imagine debugging a method
who's entry point could be in one of three places?

Lew

unread,
May 16, 2007, 5:33:13 PM5/16/07
to
Daniel Pitts wrote:
> I also find that avoiding multiple exit points leads to variable
> reuse, which is a far worse practice. Actually, I think that it makes
> sense for a method to possible have multiple exit points, as long as
> it only has one entry point :-) Can you imagine debugging a method
> who's entry point could be in one of three places?

Imagine? I can remember. I used to work on systems that allowed multiple
entry points in a routine. I agree that single entry point is much nicer.

--
Lew

Message has been deleted

Lew

unread,
May 16, 2007, 5:35:25 PM5/16/07
to
Lew wrote:
>> Ignore her advice at your peril. (Not that she's infallible, but I
>> have yet to find her in error in this forum.)

Patricia Shanahan wrote:
> BLUSH! And thanks. However,

Note that when I suggest that one ignores your advice at peril, it doesn't
mean that I endorse uncritically /following/ your advice. One should
carefully consider anyone's input, particularly those known to be
knowledgeable, but that confers no obligation to follow it afterward.


--
Lew

Martin Gregorie

unread,
May 16, 2007, 5:52:16 PM5/16/07
to
I tend to end up with a single-exit solution, but than I also tend to
lard my code fairly liberally with debugging statements (and
multi-valued debugging switches). I find that this is generally easier
to set up and works better with a single exit. This is a
language-agnostic position on my part: I use the same approach in any
language. It was proven in IDMS/COBOL systems, carried through to C and
now to Java.

I should add that I don't go to this trouble merely to debug the methods
in a particular class, but do it this way because I find the tracing
useful as I add successive classes and hierarchies of classes to a
complex process. It continues to be useful when system testing starts to
integrate intercommunicating processes.

Last but not least, it remains useful in debugging live code: a
well-thought out tracing system can, for instance, help to
distinguish between a user who didn't type what (s)he thought (s)he typed
when entering data and a genuine bug or to diagnose problems if the data
feed
from an upstream system changes in unexpected ways.

> I believe that there is a significant gain in ease of debug and change
> for languages without try-finally or equivalent. I am just not convinced
> for Java.
>

I don't find much difference, but then my philosophy is to restrict
throwing exceptions to potentially fatal situations. I generally do not
use them to signal expected non-fatal conditions such as end of file in
the grounds that the higher level classes must detect and act on them
without undue contortions, tangled logic or data loss.


--
martin@ | Martin Gregorie
gregorie. | Essex, UK
org |

Patricia Shanahan

unread,
May 16, 2007, 6:18:39 PM5/16/07
to
Stefan Ram wrote:

> Patricia Shanahan <pa...@acm.org> writes:
>> In this case, I am not so much giving advice as asking for
>> insight. Are there advantages in Java to pushing for single
>> exit that outweigh the cost of making the code more
>> complicated, for example by requiring a "retVal"? If so, what
>> are they?
>
> The usual benefits of »structured programming«.
>
> - With a single exit at the end, if I would want to add a
> call to be done once before the method exits, I would add
> it in front of this exit point. Otherwise, one would need
> to find all exit points and add this call in front of
> each one.

My question is specific to Java, so I could wrap the multi-exit code in
a try-finally and do the call in the finally block. This used to be one
of the most convincing arguments, but I'm not sure it still applies.

>
> - A kind of »referential transparency« of blocks. By this
> (ignoring parameters and return values for simplicity),
> a methode declaration
>
> m(){ ... { ... } ... }
>
> can always be refactored to
>
> m1(){ ... } // = the »{ ... }« block from above
>
> m(){ ... m1(); ... }
>
> Thus, a block can always be replaced by a call to this
> block after it has been given a name by a method
> declaration.

Not always, in Java, given the lack of call-by-reference:

m(){int x=0; int y = 0; ... { ... x = 5; y = 20; ... } ... }

cannot be refactored as above without changing the handling of x and y.
Passing them as parameters does not get the changed values back to the
surrounding block.

And one of the standard techniques for obtaining a single exit function
involves using an extra outer block variable, modified at each logical
exit point, to represent the return value.


>
> This is not possible anymore, when this block contains
> an exit (»return«).
>
> - Improved readability. In
>
> { ...
> { ... }
> f();
> ... }
>
> I know that »f();« will be executed whenever the whole
> block is executed if the block is written according to
> structured programming rules. I do not have to analyze the
> inner block to make this assertion. When jump-statements,
> like »return;« are allowed, one can not make such
> assertions with the same ease.

I'm not convinced the single exit rule does always aid readability. In
some cases, for example, I think getting one or two special cases
completely out of the way before starting the main work leads to more
readable code. It makes it easier to be sure that nothing else in the
method needs to handle the special cases, and that the special case
decision will not be overridden later on.

This is especially the case for recursive methods.

int factorial(int n){
if(n < 0){
throw something;
}
if(n == 0){
return 1;
}
return n * factorial(n-1);
}

int factorial(int n){
int fact;
if(n < 0){
throw something;
}
if(n == 0){
fact = 1;
}else{
fact = n * factorial(n-1);
}
return fact;
}

I think the multi-exit version makes it easier to identify the base case
and be sure its handling is non-recursive.

Note that I am not denying the existence of many methods for which the
single exit version will be the most readable version, and should be
used. I just feel that there are cases in which multiple exit is clearer
than single exit, and that multiple exit should be used in those cases.

Possibly the difference is whether it is more important to be sure some
code is always executed, or to be sure some code is not executed in
particular cases.

Patricia

Patricia Shanahan

unread,
May 16, 2007, 6:28:06 PM5/16/07
to
Martin Gregorie wrote:
> Patricia Shanahan wrote:
...

>> I believe that there is a significant gain in ease of debug and change
>> for languages without try-finally or equivalent. I am just not convinced
>> for Java.
>>
> I don't find much difference, but then my philosophy is to restrict
> throwing exceptions to potentially fatal situations. I generally do not
> use them to signal expected non-fatal conditions such as end of file in
> the grounds that the higher level classes must detect and act on them
> without undue contortions, tangled logic or data loss.

try-finally does not require any use of exceptions. It just provides a
way of having the finally block run on completion of the try block.

I thought single exit was a very good idea when I was programming in
assembly languages and later in C. Is it a good idea in Java, or just a
habit?

Patricia

Lew

unread,
May 16, 2007, 8:14:31 PM5/16/07
to
Patricia Shanahan wrote:
> try-finally does not require any use of exceptions. It just provides a
> way of having the finally block run on completion of the try block.
>
> I thought single exit was a very good idea when I was programming in
> assembly languages and later in C. Is it a good idea in Java, or just a
> habit?

Very interesting discussion. What I like about Patricia's suggestion is a
sense of flexibility - she seems to express a bias for single-exit structure,
but violates that principle when there is a compelling argument that another
way is clearer.

This is one of those areas where I would leave it to the practitioner, if
everyone is thinking as carefully as the respondents in this thread.
Arguments in both directions were founded on the same basic principles of code
clarity and maintainability. Whichever decision you make is likely to be
elegant for some values of elegant, if you work from such sound first principles.

If I were reviewing, say, Martin's or Patricia's code, I would not ding either
for the decisions they described here. Both would be based on intelligent
goals and clear thinking; the difference is a matter of style at that point.

At some threshold one must recognize that coding is an art, and some rules
should not become repressive. There is room for individual style.

--
Lew

printd...@gmail.com

unread,
May 16, 2007, 9:43:24 PM5/16/07
to

Having come from a procedural language background, I was always taught
5 rules that could not be broken:
1) Single Entry Point
2) Single Exit Point
3) No GOTO's allowed
4) No self-modifying code.
5) One procedure, one function

Having been trying to learn Java, I am now of the opinion that one can
still write well structured programs yet not be regimented by the
above rules, more over numbers 1 and 2.
I found this site http://ivan.truemesh.com/archives/000611.html
which appears to agree with me. And just to quote a section of the
above site,

Longer functions that use the "single exit
point" rule can get really convoluted and difficult
to understand. Having a function return as
soon as it can improves the clarity because it
improves the "locality" of the code.


Message has been deleted

Patricia Shanahan

unread,
May 17, 2007, 1:09:00 AM5/17/07
to
Stefan Ram wrote:
> Patricia Shanahan <pa...@acm.org> writes:
>> My question is specific to Java, so I could wrap the multi-exit
>> code in a try-finally and do the call in the finally block.
>
> By this finally-block you re-introduce a single exit point:
> This single exit point of the wrapped code now is the end of
> the finally block. So this wrapped code does not count as
> multi-exit code, it is single-exit code again.

Looking at it that way, I would argue that try-finally makes the
multi-exit to single-exit refactoring trivial.

Many of the familiar arguments for single-exit amount to preemptive
avoidance of ever having to do that refactoring. Without try-finally, it
really is something that should be avoided if possible.

Patricia

Martin Gregorie

unread,
May 17, 2007, 7:37:08 AM5/17/07
to
Patricia Shanahan wrote:
> I thought single exit was a very good idea when I was programming in
> assembly languages and later in C. Is it a good idea in Java, or just a
> habit?
>
Good question. As you say, it is a very good strategy in C and
assembler. It mostly works for me in Java though, as I said earlier, its
mainly conditioned by my tracing philosophy. I much prefer using trace
statements to a debugger and always leave tracing in production code.

I frequently start off writing a class with multi-exit methods for the
same reasons that you give but often switch and rewrite them as single
exit after a few methods have been written and it becomes obvious that
an exit tracing capability would be useful. Exit tracing is a real pain
for multi-exit methods and does a good job of obscuring the logic. I
realize this is probably the mark of insufficient preliminary thought
but at least I typically make the switch early in the process of coding
the class, so relatively little code needs to be restructured.

I prefer to trace the exit from a method rather than entry to it. This
allows a trace file to contain one line per method called while still
showing the method name, arguments and return value. Of course, if the
method is large and complex then increasing the trace detail level
should trace its entry and (possibly) still higher detail levels would
trace the internals. The latter tends to comes out in the wash if things
are organized so the trace detail level approximates the method call
depth in the program.

Lew

unread,
May 17, 2007, 8:24:26 AM5/17/07
to
Martin Gregorie wrote:
> Good question. As you say, it is a very good strategy in C and
> assembler. It mostly works for me in Java though, as I said earlier, its
> mainly conditioned by my tracing philosophy. I much prefer using trace
> statements to a debugger and always leave tracing in production code.

I trust you use a logging package in order not to create trouble for the
production code. I really hope you don't use System.out for your traces.

Otherwise, I would certainly ding such code in a review.

--
Lew

Patricia Shanahan

unread,
May 17, 2007, 10:51:06 AM5/17/07
to

Sounds like a very different approach to debug from mine. I tend to
collect information not just for a specific problem, but to answer a
specific question about the problem. It is possible that all exits from
some method would be the key information, but just as likely that I
would need to know about uses of a particular path inside the method.

I do sometimes want access to data from a normally running program,
without having a specific problem to debug. For example, one of my
programs uses a hill climbing heuristic that can reach a local optimum.
I often want to review its behavior. I supported that with logging calls
at points in the code where the information I need is most conveniently
available. I don't think any of them are method exits.

Patricia

tjmadd...@gmail.com

unread,
May 17, 2007, 10:59:06 AM5/17/07
to

Habit, for me. In on C project I was working on long ago, the setjmp/
longjmp was wrapped in macros to resemble TRY/CATCH/FINALLY. So a
return in the middle of the macros would corrupt the return stack, and
the program would go to undefined places. At that point, it was a hard
and unbreakable rule. But I hate complex if/else if/else constructs
more, so if you are doing something like that just to maintain a
single exit point, I'd ding it.

I've never tried, but what would happen if a return was done inside a
try/finally block?

public class Foo {
private int pg=13;
private int r = 18;
public boolean Rating(int age) {
try {
if (age > r) {
return true;
}
}
finally { return false; }
}
}

Contrived example: not real code.

Martin Gregorie

unread,
May 17, 2007, 10:40:21 AM5/17/07
to
Lew wrote:
> I trust you use a logging package in order not to create trouble for the
> production code. I really hope you don't use System.out for your traces.
>
So far all my Java code has been stand-alone executables and I have used
stderr for tracing. In this situation sending it to the system logger or
to a dedicated logging process is overkill: redirecting stderr to a file
is sufficient. However, all tracing is handled by a utility class, so
sending it elsewhere would involve a simple change to one method within
a dedicated class.

> Otherwise, I would certainly ding such code in a review.
>

I'd agree with you if I was dealing with a multi-process system.

In a complex, multi-process system I might configure the system logger
to send my tracing info to a private log file. However, its more likely
that I'd use a custom logging process, partly for portability and partly
because that allows multiple copies of the system to keep their logging
output separate.

My current project offers yet another possibility. The main process will
be run as a cron task, so the best place to send error reports or
tracing is to stderr. Crond automatically collects all output from
stdout and stderr and e-mails it to the sysadmin. Problem solved. As a
bonus there's no additional code needed to analyze or rotate logs.

Lew

unread,
May 17, 2007, 11:20:13 AM5/17/07
to
Martin Gregorie wrote:
> I'd agree with you if I was dealing with a multi-process system.
>
> In a complex, multi-process system I might configure the system logger
> to send my tracing info to a private log file. However, its more likely
> that I'd use a custom logging process, partly for portability and partly
> because that allows multiple copies of the system to keep their logging
> output separate.
>
> My current project offers yet another possibility. The main process will
> be run as a cron task, so the best place to send error reports or
> tracing is to stderr. Crond automatically collects all output from
> stdout and stderr and e-mails it to the sysadmin. Problem solved. As a
> bonus there's no additional code needed to analyze or rotate logs.

All of these are good ideas. Your analysis proves once again the triumph of
thought over dogma.

Both you and Patricia apply a variety tools to the situation, be it runtime
logging or tracing, profiling (as in Patricia's hill-climbing heuristics
example), or development-time debug statement-stepping with variable watches.
Neither seems to think that any one tool or technique is the be-all and
end-all of every related problem. Thoughtful analysis seems to inform the
choices.

Like the heuristic algorithm, programs represent local maxima of value to a
problem's solution. It is likely an untenable problem to prove that any given
program represents the absolute maximum value to a problem's solution.

I endorse the use of System.err for traces and the like. I do think logging
calls are of low enough coding overhead to justify their use even in fairly
small programs. Their main advantage there is the ability to turn them on and
off without rebuilding an app, allowing a maintainer to zero in on problems
only when they occur and virtually eliminate logging overhead otherwise.

But to insist that logging is the only solution would be to let dogma win over
thought.

--
Lew

Lew

unread,
May 17, 2007, 11:27:11 AM5/17/07
to
tjmadd...@gmail.com wrote:
> I've never tried, but what would happen if a return was done inside a
> try/finally block?
>
> public class Foo {
> private int pg=13;
> private int r = 18;
> public boolean Rating(int age) {
> try {
> if (age > r) {
> return true;
> }
> }
> finally { return false; }
> }
> }
>
> Contrived example: not real code.

For this we turn to the JLS, ss. 14.20.2:
<http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.20.2>
> A try statement with a finally block is executed by first executing the try block. Then there is a choice:
>
> * If execution of the try block completes normally, then the finally block is executed, and then there is a choice:
> o If the finally block completes normally, then the try statement completes normally.
> o If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S.

The finally return supersedes the try return.

--
Lew

Message has been deleted

Lew

unread,
May 17, 2007, 11:30:25 AM5/17/07
to
tjmadd...@gmail.com wrote:
> I've never tried, but what would happen if a return was done inside a
> try/finally block?
>
> public class Foo {
> private int pg=13;
> private int r = 18;
> public boolean Rating(int age) {
> try {
> if (age > r) {
> return true;
> }
> }
> finally { return false; }
> }
> }
>
> Contrived example: not real code.

For this we turn to the JLS, ss. 14.20.2:


<http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.20.2>
> A try statement with a finally block is executed by first executing the try block. Then there is a choice:

> ...
> * If execution of the try block completes abruptly for any other reason R, then the finally block is executed. Then there is a choice:
> o If the finally block completes normally, then the try statement completes abruptly for reason R.
> o If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).

tjmadd...@gmail.com

unread,
May 17, 2007, 11:34:06 AM5/17/07
to
On May 16, 4:28 pm, Patricia Shanahan <p...@acm.org> wrote:
> Martin Gregorie wrote:
> > Patricia Shanahan wrote:
> ...
> try-finally does not require any use of exceptions. It just provides a
> way of having the finally block run on completion of the try block.
>
> I thought single exit was a very good idea when I was programming in
> assembly languages and later in C. Is it a good idea in Java, or just a
> habit?
>
> Patricia

For me, habit. I worked a long time on a C app with setjmp/longjmp put
in TRY/CATCH/FINALLY macro constructs. If a developer did a return
inside of the macros, the return stack was corrupted. I hate
convoluted if/else logic worse, though, so I am not completely against
multiple exit points. But something like this would not be good IMHO,
even though it works as I would expect:

public class EarlyExit {

private final int ageForPG = 13;
private final int ageForR = 18;

public boolean oldEnough(int age) {
try {
if (age > ageForR) {
System.out.println("Old enough");
return true;
}
}
finally {
if (age < ageForPG) {
System.out.println("Go away, kid, ya bother me!");
return false;
}
}
System.out.println("How old are you again?");
return false;
}

public static void main(String[] args) {
EarlyExit test = new EarlyExit();
test.oldEnough(16);
test.oldEnough(21);
test.oldEnough(10);
}

}

How old are you again?
Old enough
Go away, kid, ya bother me!

Tim


printd...@gmail.com

unread,
May 17, 2007, 4:26:24 PM5/17/07
to
On May 17, 12:34 pm, "tjmadden1...@gmail.com" <tjmadden1...@gmail.com>
wrote:


I thought that the "try...finally" construct was used more for
handling exceptions. I've never seen it used as an alternate
to the if...else construct. Is this the intention of your code or am
I reading it wrong? Why are you using the try...finally
like that?

Martin Gregorie

unread,
May 17, 2007, 4:07:09 PM5/17/07
to
Maybe not that different. I suspect that an OO purist could easily throw
rocks at my class decomposition, but one result is that most of my
methods are fairly small and linear. If a method is becoming large and
complex it gets refactored into a set of private methods and the
hierarchic tracing levels adjusted so that higher debug levels will
cause the private methods to be traced. This way I don't get deluged
with low level tracing detail if I don't need to see it.

> I tend to
> collect information not just for a specific problem, but to answer a
> specific question about the problem. It is possible that all exits from
> some method would be the key information, but just as likely that I
> would need to know about uses of a particular path inside the method.
>

The way that I use debugging levels more or less maps onto this.

Another neat idea that I first saw in the depths of George 3 is to
continually generate tracing, but put the result into a circular buffer.
If a fatal error occurs the buffer gets dumped in trace event sequence.
Its useful for solving problems in long running processes without
burying yourself in debugging output, but is only suitable for processes
that don't carry much context over from one logical piece of input to
the next.

> I do sometimes want access to data from a normally running program,
> without having a specific problem to debug. For example, one of my
> programs uses a hill climbing heuristic that can reach a local optimum.
> I often want to review its behavior. I supported that with logging calls
> at points in the code where the information I need is most conveniently
> available. I don't think any of them are method exits.
>

Yes, I do that too when needed. In addition, when performance and/or
memory use is critical I'll instrument the programs in the system so
that its easy to follow performance over time. Performance data might
get written to a database, if the system uses one, or to a log file.
Either way the system would almost certainly include a performance
analysis program.

A good (non-Java) example of this occurred a while back when I was away
from home and paying for my phone usage. I made sure ppp was logging
session stats and wrote a pair of gawk programs to extract ppp session
details from the log and consolidate them into a session diary so they
could be easily reconciled with the phone bill.

Lew

unread,
May 17, 2007, 5:20:41 PM5/17/07
to
printd...@gmail.com wrote:
> I thought that the "try...finally" construct was used more for
> handling exceptions. I've never seen it used as an alternate
> to the if...else construct. Is this the intention of your code or am
> I reading it wrong? Why are you using the try...finally
> like that?

tjmadden1128 was showing an example of what to avoid.

try ... finally is not only for exceptions. The catch block is not required
if there is a finally block.

A legitimate use of try ... finally is to guarantee to clean up resources such
as connections.

<snippet>
Connection cxn = getConnection();
if ( cxn == null )
{
throw new RuntimeException( "oops!" );
}
try
{
int result = doSomethingUseful( cxn );
if ( result == 0 )
{
return;
}
result = doSomethingElseUsful( cxn );
if ( result < 0 )
{
throw new RuntimeException( "drat!" );
}
return;
}
finally
{
close( cxn );
}
</snippet>

--
Lew

tjmadd...@gmail.com

unread,
May 18, 2007, 10:33:13 AM5/18/07
to
On May 17, 2:26 pm, "printdude1...@gmail.com"

Just as a simple example, and I was curious as to how it would work.
Lew then pointed me to where the spec says what should happen.
Situations where I might use it is as Lew also posted, to ensure that
a database or socket connection or open file is closed. I would not
use it in place of an if/else construct, unless it really made code
clearer by replacing a bunch of nested if/else's. Even then, I'd think
long and hard on it.

Tim

Chris Smith

unread,
May 18, 2007, 3:25:35 PM5/18/07
to
Patricia Shanahan <pa...@acm.org> wrote:
> I thought single exit was a very good idea when I was programming in
> assembly languages and later in C. Is it a good idea in Java, or just a
> habit?

Among those who read my code, I'm somewhat famous for radically rooting
out and removing any repetition (or, as my detractors would say,
"consistency" :), so my answer is definitely biased by this. I find
that the single-exit-per-block rule prohibits certain abstractions that
I find useful. Once specific example is that when implementing equals
methods, I often find that the following pattern best expresses the
logic of the routine:

public boolean equals(Object o)
{
if (...) return false;
if (...) return false;
if (...) return false;

return true;
}

I can't find any way to write this that sticks to one exit point and
expresses the concept anywhere near as clearly, without writing an if
condition that's many lines long and blocks me from naming the results
of intermediate computations with local variables.

I would do this in other languages as well, though, even without the
try/finally construct. If I want something to happen when a function
completes, then I'd write:

someWrapper() { theRealFunction(); postprocess(); }
theRealFunction() { ... }

The only time I've really run into a major conflict about this is with
someone who wanted to add debug logging statements throughout the code.
I simply don't do that. I've learned to like AOP (despite still
believing it should be very rarely used in production) because it saves
me from having to do something that I find so utterly hideous as
sprinkling print statements throughout my code for debug logging.

So I'm definitely a little outside the mainstream, but that's my
perspective.

--
Chris Smith

0 new messages