Converting Strings to Numbers
NumberFormatException occurs when a string is not a legal representation of a number, as in Integer.parseInt("fred"), and Double.parseDouble can also throw it.
Try it: try / except / else / finally
How an exception jumps out of a try block to the first matching except clause, when else runs, and why finally always runs.
How it works
- Statements in try run until one raises an exception; the rest of try is skipped.
- Python checks the except clauses in order and runs the first one whose type matches.
- If nothing was raised, the else block runs instead.
- finally runs in every case.
Default run (9 steps): Call safe_divide('4'). … Return 25.0. Output was: Worked: 25.0 / Done.
Simplified: One fixed function; int() and / are modelled exactly (including how Python prints floats), but nothing is executed as Python.
Loading the simulation…
Where Program Data Starts as Text
Many programs receive their data as text. A user types something into a box, a file supplies a line of characters, or a web form sends a field as a String. When the program needs a number from that text, it has to convert the string into a numeric value. Sometimes that conversion succeeds, and sometimes it cannot be carried out at all. This article follows one conversion call through both of its possible outcomes and then looks at a second, unrelated kind of exception that can appear in the same situations.
What do you think happens?
Suppose str holds the text fred. What happens when Integer.parseInt(str) runs?
Reveal answer
It throws a NumberFormatException
The text fred is not a legal representation of an integer, so the conversion cannot be carried out. The source uses exactly this call, Integer.parseInt("fred"), as its example of the failure.
One Call, Two Possible Outcomes
Consider the function call Integer.parseInt(str), where str is a variable of type String. The result depends entirely on what the string contains. The same line of code can produce a number or an exception, and nothing in the call itself tells you which will happen. The contents of the string decide.
When the string is a legal representation of an integer, such as the text 42, the conversion works and the method returns the number 42. When the string is not a legal representation of a number, such as fred, the method throws a NumberFormatException instead of returning a value. An exception is a signal that something has gone wrong during execution, and it interrupts the normal flow of the program at the point where it is raised.
Read the diagram as a decision made once per call. The string either satisfies the rules for a legal number or it does not. A legal string leads to a returned value. An illegal string leads to the exception. From there, the exception either goes unhandled, in which case the program crashes, or it is handled by code the programmer has written. The source describes the unhandled case directly: if nothing is done to handle the exception, the program will crash.
Tracing a Successful and a Failing Conversion
43- The string 42 is a legal representation of an integer, so
parseIntreturns the number 42. - The returned value is stored in n and used like any other int.
Following the failing case
A variable holds the text fred and the program calls Integer.parseInt on it. Trace what happens to the normal flow of the program.
- 1Call the method
Integer.parseInt(str)runs with str equal to fred. - 2Check the text
fred is not a legal representation of an integer, so no number can be produced.
- 3Raise the exception
The method throws a
NumberFormatException, and the normal flow of the program is interrupted at this line. - 4Look for handling
If no code deals with the exception, the program crashes. If written code catches it, that code decides what happens next.
The call produces no number. The program either crashes or continues only because the programmer wrote code to deal with the exception.
Double.parseDouble works in the same way. It can also throw a NumberFormatException when it receives a string that is not a valid representation of a double. The exception has the same name in both cases because both functions convert text into a number and both can fail when the text is malformed. If you remember the rule for one, you should expect the other to fail for the same underlying reason, a string that is not a legal number.
Handling a NumberFormatException
Because a NumberFormatException interrupts the program, a careful programmer writes code that anticipates it. The source does not prescribe a specific technique, but the general idea is that the code around the conversion decides what to do when the text is not a legal number. The programmer might report the problem to the user, ask for the input again, or use a default. The important point from the source is that the exception does not fix itself. Without that handling, the program crashes.
That is not a whole number.- The conversion is placed inside a try block, so the program can react to a failure.
- The catch block runs only when
parseIntthrows aNumberFormatException, and this is the programmer's choice of response.
Where an IllegalArgumentException Comes From
The second kind of exception has a different cause. An IllegalArgumentException can occur when an illegal value is passed as a parameter to a subroutine. The problem is not in converting text. The problem is that the value handed to the subroutine is not one the subroutine accepts. The source gives the typical case: if a subroutine requires that a parameter be greater than or equal to zero, an IllegalArgumentException might occur when a negative value is passed to it.
Tracing an IllegalArgumentException Up the Call Stack
The diagram below shows a three-level chain of subroutine calls. The main method calls a computing subroutine, which passes a negative value to a subroutine that requires a non-negative parameter. That subroutine raises the exception. Each frame in the chain is still active when the exception is raised, and the exception moves back up through those frames until some code handles it or none does.
In the diagram, the setRate subroutine is the frame that detects the illegal value and raises the exception. The exception then travels back toward the frames that called it, computeRate and then main. Whether the program crashes or recovers depends on what those frames contain. If none of them has code that handles the exception, the program crashes. If one of them has handling code, that frame decides how the program responds. The source's point that the response is decided by the subroutine's author applies here: the author of setRate decided to raise the exception, and the authors of the calling code decide whether to handle it.
Telling the Two Exceptions Apart
Both exceptions signal that a value was not acceptable, but they arise from different situations. The table sets the two side by side so that their causes can be compared directly. The key question for each is where the bad value came from and what kind of check failed.
| Feature | NumberFormatException | IllegalArgumentException |
|---|---|---|
| Typical trigger | Integer.parseInt("fred") or Double.parseDouble on malformed text | A subroutine receives an illegal parameter, such as a negative value where a non-negative one is required |
| Where the problem is | In the text being converted to a number | In the value passed into a subroutine |
| What went wrong | The string is not a legal representation of a number | The value is not one the subroutine accepts |
| Is the response fixed? | Without handling, the program crashes | The response is decided by the subroutine's author, so it is a common response rather than a guaranteed one |
Causes of the two exceptions described in the source
Mistakes Learners Often Make
Common mistake Assuming a failed conversion quietly returns zero
What it looks likeInteger.parseInt("fred") is expected to return 0.Why it failsThe source states that the illegal string causes a
NumberFormatExceptionto be thrown, not that a default value is returned.Do this insteadExpect an exception, and write code that handles it if the program should continue.
Common mistake Treating both exceptions as the same kind of problem
Why it failsNumberFormatExceptioncomes from the text being converted, whileIllegalArgumentExceptioncomes from an illegal parameter passed to a subroutine.Do this insteadAsk whether the bad value was text that could not become a number, or a value a subroutine refused to accept.
Common mistake Assuming an IllegalArgumentException always happens for a bad parameter
Why it failsThe source says the response to an illegal parameter is decided by the subroutine's author, so it is not guaranteed.
Do this insteadCheck the documentation or the code of the subroutine to see how it responds to illegal input.
Common mistake Leaving a conversion unprotected in a program that must keep running
Why it failsIf nothing handles the exception, the program crashes.
Do this insteadPlace handling code around conversions whose input could be malformed.
Checking Your Understanding of Conversion Outcomes
A program calls Integer.parseInt on the text 42 and then on the text fred. For each call, state whether a number is returned or a NumberFormatException is thrown, and explain what determines which outcome occurs.
Hints
- Look at whether the string is a legal representation of a number.
- The contents of the string decide the outcome, not the method name.
A subroutine named setRate requires its parameter to be greater than or equal to zero. Another method passes it the value -5. Which exception describes this situation, and which part of the program decides whether the program crashes?
Hints
- The bad value is a parameter to a subroutine, not text being converted.
- The source says the response is decided by the subroutine's author and that the program crashes if nothing handles the exception.
Key Takeaways
Integer.parseIntandDouble.parseDoublereturn a number for a legal string such as 42, but throw aNumberFormatExceptionfor a string such as fred that is not a legal representation of a number.- A
NumberFormatExceptioncomes from the text being converted; if no code handles it, the program crashes. - An
IllegalArgumentExceptioncomes from an illegal parameter passed to a subroutine, such as a negative value where a non-negative one is required. - The response to an illegal parameter is decided by the subroutine's author, so
IllegalArgumentExceptionis a common response rather than a guaranteed one.