Seeing as Java doesn\'t have nullable types, nor does it have a TryParse(), how do you handle input validation without throwing an exceptions?
The usual way:
I'm going to restate the point that stinkyminky was making towards the bottom of the post:
A generally well accepted approach validating user input (or input from config files, etc...) is to use validation prior to actually processing the data. In most cases, this is a good design move, even though it can result in multiple calls to parsing algorithms.
Once you know that you have properly validated the user input, then it is safe to parse it and ignore, log or convert to RuntimeException the NumberFormatException.
Note that this approach requires you to consider your model in two pieces: the business model (Where we actually care about having values in int or float format) and the user interface model (where we really want to allow the user to put in whatever they want).
In order for the data to migrate from the user interface model to the business model, it must pass through a validation step (this can occur on a field by field basis, but most scenarios call for validation on the entire object that is being configured).
If validation fails, then the user is presented with feedback informing them of what they've done wrong and given a chance to fix it.
Binding libraries like JGoodies Binding and JSR 295 make this sort of thing a lot easier to implement than it might sound - and many web frameworks provide constructs that separate user input from the actual business model, only populating business objects after validation is complete.
In terms of validation of configuration files (the other use case presented in some of the comments), it's one thing to specify a default if a particular value isn't specified at all - but if the data is formatted wrong (someone types an 'oh' instead of a 'zero' - or they copied from MS Word and all the back-ticks got a funky unicode character), then some sort of system feedback is needed (even if it's just failing the app by throwing a runtime exception).
Integer.MIN_VALUE as NumberFormatException is bad idea.
You can add proposal to Project Coin to add this method to Integer
@Nullable public static Integer parseInteger (String src)... it will return null for bad input
Then put link to your proposal here and we all will vote for it!
PS: Look at this http://msdn.microsoft.com/en-us/library/bb397679.aspx this is how ugly and bloated it could be
I asked if there were open source utility libraries that had methods to do this parsing for you and the answer is yes!
From Apache Commons Lang you can use NumberUtils.toInt:
// returns defaultValue if the string cannot be parsed.
int i = org.apache.commons.lang.math.NumberUtils.toInt(s, defaultValue);
From Google Guava you can use Ints.tryParse:
// returns null if the string cannot be parsed
// Will throw a NullPointerException if the string is null
Integer i = com.google.common.primitives.Ints.tryParse(s);
There is no need to write your own methods to parse numbers without throwing exceptions.
For Java 8+, I would probably use RegEx to pre-filter (to avoid the exception as you noted) and then wrap the result in a primitive optional (to deal with the "default" problem):
public static OptionalInt toInt(final String input) {
return input.matches("[+-]?\\d+")
? OptionalInt.of(Integer.parseInt(input))
: OptionalInt.empty();
}
If you have many String inputs, you might consider returning an IntStream
instead of OptionalInt
so that you can flatMap()
.