What is the proper way to handle a NumberFormatException when it is expected?

82,574

Solution 1

  • Is there a method that I can call that will tell me if Integer.parseInt() will throw a NumberFormatException before calling it? Then I would have no problem logging this, since it should never happen.

Sadly, no. At least not in the core Java API. It's easy to write one, however - just modify the code below.

  • If I simply do not catch the exception, will the valiable not get assigned? Then I will simply initialize it to the value that I want when it's not a number and not catch the exception.

If you do not catch the exception then the stack will unwind until it hits a catch block that will handle it, or it will unwind completely and halt the thread. The variable will, in fact, not be assigned but this is not exactly what you want.

  • Is there a way to mark the exception somehow explicitly that I don't care about it? I'm thinking this would be something similar to AWTEvent.consume(). If so, then I will do this so that Google CodePro doesn't see this as "unlogged".

There may be a way to tell CodePro to ignore this particular warning. Certainly with tools like FindBugs and Checkstyle you can turn off warnings in specific locations. (EDIT: @Andy has pointed out how to do this.)

I suspect what you want is something like the Commons lang package mentioned by @daveb. It's pretty easy to write such a function:

int parseWithDefault(String s, int def) {
    try {
        return Integer.parseInt(s);
    }
    catch (NumberFormatException e) {
        // It's OK to ignore "e" here because returning a default value is the documented behaviour on invalid input.
        return def;
    }
}

Solution 2

There is NumberUtils.toInt(String, int) in commons lang which will do exactly what you want.

NumberUtils.toInt("123", 42) ==> 123
NumberUtils.toInt("abc", 42) ==> 42

Solution 3

* Is there a way to mark the exception somehow explicitly that I don't care about it? I'm thinking this would be something similar to AWTEvent.consume(). If so, then I will do this so that Google CodePro doesn't see this as "unlogged".

Yes, you can locally disable a CodePro audit rule for one line of code:

http://code.google.com/javadevtools/codepro/doc/features/audit/locally_disabling_audit_rules.html

That said, it is not necessarily required to include diagnostic logging in every exception catch block. Sometimes, the best action is to take a default course. Sometime it's to interact with the user. It depends.

Solution 4

Create your own convenience method for now and future use:

public static int parseInt(final /*@Nullable*/ String s, final int valueIfInvalid) {
    try {
        if (s == null) {
            return valueIfInvalid;
        } else {
            return Integer.parseInt(s);
        }
    } catch (final NumberFormatException ex) {
        return valueIfInvalid;
    }
}

Is there a method that I can call that will tell me if Integer.parseInt() will throw a NumberFormatException before calling it? Then I would have no problem logging this, since it should never happen.

Not that I'm aware of. Keep in mind that if there were, you likely end up parsing the value twice (once to validate and once to parse it). I understand you want to avoid the exception, but in this case, this is catching the exception is the standard idiom in Java and it doesn't provide another (at least that I know of).

If I simply do not catch the exception, will the valiable not get assigned? Then I will simply initialize it to the value that I want when it's not a number and not catch the exception.

You must catch the exception (even if it does nothing) or it will escape the block and throw up through the stack.

Is there a way to mark the exception somehow explicitly that I don't care about it? I'm thinking this would be something similar to AWTEvent.consume(). If so, then I will do this so that Google CodePro doesn't see this as "unlogged".

I don't know of any. I would use the above convenience method (I have something similar in a small collection of general utilities I have available for use on my all projects).

I wouldn't log it if its truly a normal condition that you are handling. I'm not familiiar with Google CodePro, but I would hope there is a way to suppress the warning, e.g. some sort of @SuppressWarnings("xxx") annotation/keyword.


Edit: I wanted to point out these comments in the comments below

This approach still doesn't handle the exception. It's bad form to catch an exception and do nothing with it. This is why I am looking for a better solution

.

... The exception (the situation) is being handled by returning the indicated valueIfInvalid. The "bad form" you are referring to the poor practice of blindly and unthinkingly writing empty catch blocks and never going back to truly consider and address the case. If the exception situation is considered and does the right thing for the situation (even if the right thing is to do nothing), then you've "handled" the exception.

Share:
82,574
Erick Robertson
Author by

Erick Robertson

I'm now a full-time game developer. I have focused on high-performance server work and Swing client work in the past. I've developed in multiple languages on multiple platforms, working seriously with Java, PHP, ASP, Unix C/C++, MS SQL Server, and MySQL. I take a very direct approach to programming. I don't bow to convention simply because it is. Remember that DOS was a standard at one point. Remember that Windows still is a standard. Does it work, yes, I suppose, most of the time it does. I would build it much differently.

Updated on July 09, 2022

Comments

  • Erick Robertson
    Erick Robertson almost 2 years

    I'm running into this situation where I need to parse a String into an int and I don't know what to do with the NumberFormatException. The compiler doesn't complain when I don't catch it, but I just want to make sure that I'm handling this situation properly.

    private int getCurrentPieceAsInt() {
        int i = 0;
        try {
            i = Integer.parseInt(this.getCurrentPiece());
        } catch (NumberFormatException e) {
            i = 0;
        }
        return i;
    }
    

    I want to just simplify my code like this. The compiler doesn't have a problem with it, but the thread dies on the NumberFormatException.

    private int getCurrentPieceAsInt() {
        int i = 0;
        i = Integer.parseInt(this.getCurrentPiece());
        return i;
    }
    

    Google CodePro wants me to log the exception in some way, and I agree that this is best practice.

    private int getCurrentPieceAsInt() {
        int i = 0;
        try {
            i = Integer.parseInt(this.getCurrentPiece());
        } catch (NumberFormatException e) {
            i = 0;
            e.printStackTrace();
        }
        return i;
    }
    

    I want this method to return 0 when the current piece is not a number or cannot be parsed. When I don't catch the NumberFormatException explicitly, does it not assign the variable i? Or is there some default value that Integer.parseInt() returns?

    General style says that if I catch an exception, I should log it somewhere. I don't want to log it. It's normal operation for this exception to be thrown sometimes, which also doesn't sit well with me. I cannot find a function, however, which will tell me if Integer.parseInt() will throw an exception. So my only course of action seems to be to just call it and catch the exception.

    The javadoc for parseInt doesn't help much.

    Here are the specific questions I'd like to know:

    • Is there a method that I can call that will tell me if Integer.parseInt() will throw a NumberFormatException before calling it? Then I would have no problem logging this, since it should never happen.
    • If I simply do not catch the exception, will the valiable not get assigned? Then I will simply initialize it to the value that I want when it's not a number and not catch the exception.
    • Is there a way to mark the exception somehow explicitly that I don't care about it? I'm thinking this would be something similar to AWTEvent.consume(). If so, then I will do this so that Google CodePro doesn't see this as "unlogged".
  • Erick Robertson
    Erick Robertson over 13 years
    Can't I do this in some way without importing Apache Commons?
  • daveb
    daveb over 13 years
    Yep, but many projects use commons lang so don't need to roll their own impl.
  • Erick Robertson
    Erick Robertson over 13 years
    I've so far avoided doing either.
  • Erick Robertson
    Erick Robertson over 13 years
    This approach still doesn't handle the exception. It's bad form to catch an exception and do nothing with it. This is why I am looking for a better solution.
  • Erick Robertson
    Erick Robertson over 13 years
    Then what do I do with it after I catch it? I don't want to log it, because it is normal. It's not an exception case. Leaving it unlogged works, but catching an exception and doing nothing with it is bad form. I am looking for a better answer.
  • Erick Robertson
    Erick Robertson over 13 years
    What can I do with the exception to explicitly mark it as handled? It is bad form to catch an exception and do nothing with it, so I am seeking a better solution.
  • Erick Robertson
    Erick Robertson over 13 years
    Precisely. This is why I am seeking a way to mark the exception as handled without logging it.
  • Cameron Skinner
    Cameron Skinner over 13 years
    It's not bad form if you know that you really don't want to do anything with it. It's only bad form to ignore exceptions that you should be doing something useful with.
  • Bert F
    Bert F over 13 years
    @Erick - I concur with @Cameron. The exception (the situation) is being handled by returning the indicated valueIfInvalid. The general notion of "unhandled exception" is referring to the poor practice of blindly and unthinkly writing empty catch blocks and never going back to truly consider and address the case. If the exception situation is considered and does the right thing for the situation (even if the right thing is to do nothing), you've "handled" the exception.
  • palAlaa
    palAlaa over 13 years
    @Bert F- what does final exception mean?
  • Bert F
    Bert F over 13 years
    @Alaa - final keyword - just a habit of mine - just means the ex variable will never be assigned another value. See stackoverflow.com/questions/137868/…
  • nojo
    nojo over 13 years
    no, it's not bad form to catch an exception and do nothing with it. The point of checked exceptions is so that you can catch them and handle them how your application needs to - sometimes that involves logging or recovery, but sometimes you know that it doesn't matter.
  • Steve Kuo
    Steve Kuo over 13 years
    CodePro is incorrect in requiring logging for every catch. In this case it's perfectly okay to eat the exception since that is the desired and documented behavior of the method.
  • palAlaa
    palAlaa over 13 years
    @ Steve Kuo- final can nerver be clutter
  • Joseph Lust
    Joseph Lust over 9 years
    NumberUtils just catches it in there. Doesn't get around catching it. :)