Back to Primitive Types & Wrappers
Q8Question 8 of 11

What happens when you parse an invalid number?

Key Concepts
  • Integer.parseInt("abc") throws NumberFormatException (unchecked, extends IllegalArgumentException)
  • Also throws for: empty string, null, overflow (value > Integer.MAX_VALUE), whitespace, commas
  • Parse other bases: parseInt("FF", 16) → 255 (hex), parseInt("1010", 2) → 10 (binary)
  • Convert back: toHexString(255) → "ff", toBinaryString(10) → "1010"
  • Never silently default on parse failure in banking – log and route the bad record
  • Money: always parse into BigDecimal from String, never into int or double

Definition

parseInt throws NumberFormatException for invalid input. Use the radix overload to parse hex (base 16) or binary (base 2). Use toHexString/toBinaryString to convert back.

Three things to know about number parsing:

  • Invalid input throws. Integer.parseInt("abc") throws NumberFormatException. Same for empty strings, null, overflow, and stray characters.
  • Radix overload. Integer.parseInt("FF", 16) parses hexadecimal and returns 255. parseInt("1010", 2) parses binary and returns 10.
  • Reverse conversion. Integer.toHexString(255) returns "ff". Integer.toBinaryString(10) returns "1010".

A bank teller reads an amount written on a slip. If it says "abc" where a number should be, the teller raises an error rather than guessing. Sometimes amounts arrive in hex code from a payment terminal: the teller uses a hex codebook to decode "FF" into 255. And when the bank needs to print a status flag in binary, it converts the number using the binary codebook.

Understanding the Concepts

What exactly throws NumberFormatException?

JAVA
// All of these throw NumberFormatException:
Integer.parseInt("abc");           // not a number
Integer.parseInt("");              // empty string
Integer.parseInt(null);            // null
Integer.parseInt("12.5");          // decimal point not valid for int
Integer.parseInt("1,000");         // comma not valid
Integer.parseInt("  42  ");        // whitespace not valid (trim first!)
Integer.parseInt("99999999999");   // exceeds Integer.MAX_VALUE
Integer.parseInt("42L");           // L suffix is for source code, not parsing

NumberFormatException is unchecked (extends IllegalArgumentException). The compiler does not force you to catch it, but any code parsing external input should.

How do you handle parse failures safely?

JAVA
// BAD: crashes on invalid input
int count = Integer.parseInt(userInput);

// GOOD: catch and handle
public OptionalInt safeParse(String input) {
    if (input == null || input.isBlank()) {
        return OptionalInt.empty();
    }
    try {
        return OptionalInt.of(Integer.parseInt(input.trim()));
    } catch (NumberFormatException e) {
        log.warning("Invalid number: '" + input + "'");
        return OptionalInt.empty();
    }
}

// Usage:
int count = safeParse(rawField).orElse(0);

In banking, never silently default. Log the bad input and route the record for investigation.

How do you parse hex, binary, and octal?

JAVA
// Hexadecimal (base 16)
int hex = Integer.parseInt("FF", 16);       // 255
int hex2 = Integer.parseInt("1A3F", 16);    // 6719

// Binary (base 2)
int bin = Integer.parseInt("1010", 2);      // 10
int bin2 = Integer.parseInt("11111111", 2); // 255

// Octal (base 8)
int oct = Integer.parseInt("777", 8);       // 511

// Any base from 2 to 36
int base36 = Integer.parseInt("ZZ", 36);    // 1295

// Invalid digit for the radix also throws
try {
    Integer.parseInt("2", 2);  // '2' is not a valid binary digit
} catch (NumberFormatException e) {
    System.out.println("Invalid binary digit");
}

How do you convert a number back to hex, binary, or octal?

JAVA
int value = 255;

System.out.println(Integer.toHexString(value));    // "ff"
System.out.println(Integer.toBinaryString(value)); // "11111111"
System.out.println(Integer.toOctalString(value));  // "377"
System.out.println(Integer.toString(value, 36));   // "73" (any base 2-36)

// For negative numbers, toHexString uses the unsigned bit pattern:
System.out.println(Integer.toHexString(-1));  // "ffffffff" (all bits set)
// But toString with radix includes the sign:
System.out.println(Integer.toString(-1, 16)); // "-1"

How do you parse Long, Double, and BigDecimal?

JAVA
// Long: for large values like timestamps
long timestamp = Long.parseLong("1698765432000");

// Double: for scientific values (never for money)
double rate = Double.parseDouble("8.5");

// BigDecimal: for money (always from String constructor)
BigDecimal balance = new BigDecimal("1000000.50");
// WRONG: new BigDecimal(1000000.50) captures double imprecision

Each wrapper has its own parse method. They all throw NumberFormatException on invalid input.

What about leading zeros and signs?

JAVA
Integer.parseInt("+42");    // 42 (leading + is valid)
Integer.parseInt("-42");    // -42 (leading - is valid)
Integer.parseInt("042");    // 42 (leading zeros are valid in base 10, NOT octal)
// Note: parseInt("042") is 42, not 34. It does NOT auto-detect octal.
// For octal, use parseInt("42", 8) explicitly.

What are common mistakes?

  • Not trimming input. parseInt(" 42 ") throws. Always .trim() first.
  • Silently defaulting on failure. catch (NFE e) { return 0; } hides data quality problems. Log and route.
  • Assuming parseInt detects the base. parseInt("0xFF") throws. Remove the prefix and use parseInt("FF", 16).
  • Parsing money into int or double. Always use new BigDecimal("...") for money.
  • Ignoring overflow. parseInt("3000000000") throws because 3 billion exceeds int range. Use Long.parseLong() or BigInteger.

What should a senior engineer know?

  • Java has no tryParse. Unlike C# which returns false for invalid input, Java throws. You must write your own safe-parse method or use a library.
  • Integer.decode() handles prefixes: Integer.decode("0xFF") returns 255, Integer.decode("077") returns 63 (octal). But it returns Integer, not int.
  • Spring Boot @RequestParam automatically parses and returns 400 Bad Request on NumberFormatException. You can customize the error response with @ExceptionHandler.
  • In batch pipelines, always parse inside a try-catch per record so one bad record does not abort the entire batch.

Visual Overview

DIAGRAM
  Input string → parseInt(string, radix)
    │
    ├─ valid number in radix → return int value
    │
    └─ invalid → NumberFormatException
         ├ "abc"       not numeric
         ├ ""          empty
         ├ null        null
         ├ "1,000"     comma not valid
         ├ "  42  "    whitespace (trim first)
         ├ overflow    > Integer.MAX_VALUE
         └ bad digit   "2" in base 2

  Radix parsing:
    parseInt("FF", 16)    → 255      (hex)
    parseInt("1010", 2)   → 10       (binary)
    parseInt("777", 8)    → 511      (octal)

  Reverse:
    toHexString(255)      → "ff"
    toBinaryString(10)    → "1010"
    toString(255, 36)     → "73"

Key Takeaway

When Integer.parseInt receives a string it cannot interpret as a valid integer, it throws NumberFormatException. This happens for non-numeric text, empty strings, null, values with whitespace or commas, and numbers that overflow the int range. The exception is unchecked, so the compiler does not force you to handle it, but any code parsing external input should catch it, log the bad value, and route the record for investigation.

To parse numbers in other bases, use the radix overload: parseInt("FF", 16) for hex, parseInt("1010", 2) for binary. The radix must be 2 to 36. An invalid digit for the chosen base also throws. To convert back, use toHexString(), toBinaryString(), or toString(value, radix).

In banking, never silently default on a parse failure. A silent catch { return 0; } hides data quality problems. Log the bad input and route it. And never parse money into int or double: always use new BigDecimal("...") from a String.

One sentence to remember: parseInt throws NumberFormatException on any invalid input, use the radix overload for hex and binary, and always handle the exception explicitly in production code.

---

Share
Use ← → arrow keys to navigate