How to check if a String is numeric in Java


How would you check if a String was a number before parsing it?

11/29/2015 7:15:15 PM

Accepted Answer

With Apache Commons Lang 3.5 and above: NumberUtils.isCreatable or StringUtils.isNumeric.

With Apache Commons Lang 3.4 and below: NumberUtils.isNumber or StringUtils.isNumeric.

You can also use StringUtils.isNumericSpace which returns true for empty strings and ignores internal spaces in the string. Another way is to use NumberUtils.isParsable which basically checks the number is parsable according to Java. (The linked javadocs contain detailed examples for each method.)

1/7/2020 9:05:58 AM

if you are on android, then you should use:

android.text.TextUtils.isDigitsOnly(CharSequence str)

documentation can be found here

keep it simple. mostly everybody can "re-program" (the same thing).


Java 8 lambda expressions.

String someString = "123123";
boolean isNumeric = someString.chars().allMatch( Character::isDigit );

As @CraigTP had mentioned in his excellent answer, I also have similar performance concerns on using Exceptions to test whether the string is numerical or not. So I end up splitting the string and use java.lang.Character.isDigit().

public static boolean isNumeric(String str)
    for (char c : str.toCharArray())
        if (!Character.isDigit(c)) return false;
    return true;

According to the Javadoc, Character.isDigit(char) will correctly recognizes non-Latin digits. Performance-wise, I think a simple N number of comparisons where N is the number of characters in the string would be more computationally efficient than doing a regex matching.

UPDATE: As pointed by Jean-François Corbett in the comment, the above code would only validate positive integers, which covers the majority of my use case. Below is the updated code that correctly validates decimal numbers according to the default locale used in your system, with the assumption that decimal separator only occur once in the string.

public static boolean isStringNumeric( String str )
    DecimalFormatSymbols currentLocaleSymbols = DecimalFormatSymbols.getInstance();
    char localeMinusSign = currentLocaleSymbols.getMinusSign();

    if ( !Character.isDigit( str.charAt( 0 ) ) && str.charAt( 0 ) != localeMinusSign ) return false;

    boolean isDecimalSeparatorFound = false;
    char localeDecimalSeparator = currentLocaleSymbols.getDecimalSeparator();

    for ( char c : str.substring( 1 ).toCharArray() )
        if ( !Character.isDigit( c ) )
            if ( c == localeDecimalSeparator && !isDecimalSeparatorFound )
                isDecimalSeparatorFound = true;
            return false;
    return true;

Google's Guava library provides a nice helper method to do this: Ints.tryParse. You use it like Integer.parseInt but it returns null rather than throw an Exception if the string does not parse to a valid integer. Note that it returns Integer, not int, so you have to convert/autobox it back to int.


String s1 = "22";
String s2 = "22.2";
Integer oInt1 = Ints.tryParse(s1);
Integer oInt2 = Ints.tryParse(s2);

int i1 = -1;
if (oInt1 != null) {
    i1 = oInt1.intValue();
int i2 = -1;
if (oInt2 != null) {
    i2 = oInt2.intValue();

System.out.println(i1);  // prints 22
System.out.println(i2);  // prints -1

However, as of the current release -- Guava r11 -- it is still marked @Beta.

I haven't benchmarked it. Looking at the source code there is some overhead from a lot of sanity checking but in the end they use Character.digit(string.charAt(idx)), similar, but slightly different from, the answer from @Ibrahim above. There is no exception handling overhead under the covers in their implementation.


Do not use Exceptions to validate your values. Use Util libs instead like apache NumberUtils:



Please notice that, if your string starts with an 0, NumberUtils will interpret your value as hexadecimal.

NumberUtils.isNumber("07") //true
NumberUtils.isNumber("08") //false