What is the proper way to handle a NumberFormatException when it is expected?
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.
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, 2022Comments
-
Erick Robertson almost 2 years
I'm running into this situation where I need to parse a
String
into anint
and I don't know what to do with theNumberFormatException
. 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 theNumberFormatException
explicitly, does it not assign the variablei
? Or is there some default value thatInteger.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 aNumberFormatException
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".
- Is there a method that I can call that will tell me if
-
Erick Robertson over 13 yearsCan't I do this in some way without importing Apache Commons?
-
daveb over 13 yearsYep, but many projects use commons lang so don't need to roll their own impl.
-
Erick Robertson over 13 yearsI've so far avoided doing either.
-
Erick Robertson over 13 yearsThis 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 over 13 yearsThen 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 over 13 yearsWhat 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 over 13 yearsPrecisely. This is why I am seeking a way to mark the exception as handled without logging it.
-
Cameron Skinner over 13 yearsIt'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 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 over 13 years@Bert F- what does final exception mean?
-
Bert F over 13 years@Alaa -
final
keyword - just a habit of mine - just means theex
variable will never be assigned another value. See stackoverflow.com/questions/137868/… -
nojo over 13 yearsno, 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 over 13 yearsCodePro 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 over 13 years@ Steve Kuo- final can nerver be clutter
-
Joseph Lust over 9 yearsNumberUtils just catches it in there. Doesn't get around catching it. :)