while(true) { try{ ... } catch(Exception e) { ... } }

Discussion in 'Java' started by imanhp, Feb 5, 2006.

  1. imanhp

    imanhp Guest

    Hi.

    I have a small problem here with my try/catch inside a while loop.
    Im doing a quick and dirty forced read like so:

    -----------------------------------------------------------------
    Scanner inp = new Scanner(System.in);
    PrintStream out = System.out;
    double num = 0;

    while(true) {
    try { num = inp.nextDouble(); return num; }
    catch(Exception e) { out.println("reenter value: "); }
    }
    ------------------------------------------------------------------

    The problem is that try clause wont be tried again in the while loop
    if a enter a non numeric input the first time.

    As if the exception cant be ignored for some reason.
    The code will just wind up printing "reenter value: " forever.

    Why is this and how do i fix it?


    cheers
    //iman
     
    imanhp, Feb 5, 2006
    #1
    1. Advertisements

  2. Hi,
    The why seems obvious to me, nextDouble() sees a non number so throws an
    exception and stays where it is. When the while reenters it sees the same
    non-number and throws again the exception etc.

    The fix I do not know, never having used the Scanner class.

    You have to somehow make it all start again on the next input.

    claudio
     
    Claudio Nieder, Feb 5, 2006
    #2
    1. Advertisements

  3. imanhp

    Roedy Green Guest

    this does not make any sense. Why bother with the loop? The first time
    through you exit the method.
     
    Roedy Green, Feb 6, 2006
    #3
  4. imanhp

    JScoobyCed Guest

    Somehow it does make sense. I guess imanhp wants to loop until a decimal
    value is entered. If the user enters a decimal at the first time, then
    you exit the loop.

    A quick fix to the initial code:
    <code>
    Scanner inp = null;
    PrintStream out = System.out;
    double num = 0;
    while(true) {
    inp = new Scanner(System.in);
    try {
    num = inp.nextDouble();
    return num;
    }
    catch(Exception e) { out.println("reenter value: "); }
    }
    </code>
     
    JScoobyCed, Feb 6, 2006
    #4
  5. Hi,

    Have a look at this code:

    public class TryNumberParse {
    public static void main( String[] args ) {
    double num = 0.0;

    while( true ) {
    try {
    System.out.print( "Enter a value: " );
    System.out.println( "The value entered was: " + ( num =
    getNum() ) );
    } catch( Exception e ) {
    System.out.println( "Invalid value, please re-enter...
    " );
    continue;
    }
    }
    }

    private static double getNum() {
    Scanner inp = new Scanner( System.in );
    return inp.nextDouble();
    }
    }

    Hope it helps!
     
    Ranganath Kini, Feb 6, 2006
    #5
  6. imanhp

    zero Guest

    wrote in @g44g2000cwa.googlegroups.com:

    A loop with an always-true condition is usually a *very* bad idea. Only
    experienced programmers should ever do this, and only with a very good
    reason.

    You should also try to avoid using exceptions for common problems, such
    as this input problem. The Scanner class provides methods to avoid
    exactly this.

    Here is some improved code, with a lot of comments to help you
    understand why it is better:

    Scanner inp = new Scanner( System.in );
    // ask for the first value
    System.out.print("enter value: ");
    // as long as the user doesn't enter a double
    // this is much more intuitive than "as long
    // as true is true", as the original code said
    while(!inp.hasNextDouble())
    {
    // ask to re-enter the value
    System.out.print("re-enter value: ");
    // skip the incorrect value
    inp.next();
    }
    // inp.hasNextDouble returned true, so we are
    // sure that there is a double value in the
    // Scanner - no need for exceptions
    Double d = inp.nextDouble();
    System.out.println("value entered: " + d);
     
    zero, Feb 6, 2006
    #6
  7. Aren't try/catch blocks also fairly expensive? Putting one inside a
    while loop seems like a bad habit. Granted, in this particular case,
    the intention is for the loop to iterate very few times, and the loop
    is also dependent on user input, which will in any case be much slower
    than whatever code is being processed.

    Still, it seems like something to avoid, much like always-true loops.
     
    Monique Y. Mudama, Feb 6, 2006
    #7
  8. zero sez:
    And reading user input tends to be one of them. Typical scenario
    is when you want to give them a limited number of tries (loop
    with a counter: for), validate the input (post-condition loop:
    do .. while), *and* let them hit Esc and abort the whole thing
    (break/exit in the middle). It doesn't really fit into any of
    the proper structured programming constructs, so you might as
    well go for while(1).

    Dima
     
    Dimitri Maziuk, Feb 6, 2006
    #8
  9. imanhp

    zero Guest

    Yep, that's one of the main reasons to use alternatives when they are
    available. The program flow with try/catch blocks is very complex - even
    more so if there's a finally block - and require a lot of internal
    computations.

    Which does not mean you have to stay away from exceptions altogether.
    Structured exception handling is a very good thing, as long as it is used
    for what it was envisioned to do: handle exceptional situations, not
    situations that happen in normal program flow. Incorrect user input falls
    under the normal category.
     
    zero, Feb 6, 2006
    #9
  10. Unless you are of the Single Entry Single Exit (SESE) persuasion, using
    a break or return to exit a loop seems reasonable. Using an auxiliary
    boolean variable complicates matters. Duplicating conditions is
    repeating yourself (keep it DRY).
    Not really.

    Creating exceptions is excessively expensive. Throwing exceptions is
    moderately expensive.

    Remember that a synchronised block is effectively a try/finally. We have
    known synchronisation (in normal circumstances) isn't expensive for
    years. Perhaps you the worst thing you can say about try blocks in
    relation to performance is that they may prevent inlining on some JVMs.

    Tom Hawtin
     
    Thomas Hawtin, Feb 6, 2006
    #10
  11. imanhp

    Chris Uppal Guest

    No. It's implementation-dependent but there is no reason (given any reasonable
    implementation technology) why it should have /any/ direct time cost at all.

    The indirect costs may be non-zero. For instance a try/catch might interfere
    with optimisation in the JIT (if any). The records required to implement
    zero-cost try/catch take up some space, and hence some (tiny) time too. But I
    doubt if such effects are worth worrying about in most cases.

    Actually throwing/catching an exception is, naturally, a different kettle of
    fish entirely.

    -- chris
     
    Chris Uppal, Feb 7, 2006
    #11
  12. What does DRY mean?
     
    Monique Y. Mudama, Feb 7, 2006
    #12
  13. Don't Repeat Yourself.

    "DRY says that every piece of system knowledge should have one
    authoritative, unambiguous representation. Every piece of knowledge in
    the development of something should have a single representation. A
    system's knowledge is far broader than just its code. It refers to
    database schemas, test plans, the build system, even documentation."
    -- http://www.artima.com/intv/dryP.html

    In this narrow case, the little piece of system knowledge was when to
    exit the loop.

    Tom Hawtin
     
    Thomas Hawtin, Feb 7, 2006
    #13
  14. Ah. Thank you. I hadn't heard of the acronym, but I agree with the
    sentiment!
     
    Monique Y. Mudama, Feb 7, 2006
    #14
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.