The difference between valueOf and parseInt in Java

Preface

In programming, when encountering type conversion, it seems that parseIntand are often used valueOf. Of course, only the type is used for statement here Integer, and other types are the same;

There must be readers who, like me, often use these two methods interchangeably, but don’t know what the difference is between the two. Let’s explore it next;  

the difference

  • Integer.parseInt(s)The function is to parse the string s into a signed basic type int;
  • Integer.valueOf(s)Parse the string s into the Integer object type, and the returned object can call methods in Integer;

Next, analyze the source code one by one;  

parseInt

We first click into parseInt()the method,

public static int parseInt(String s) throws NumberFormatException {
    return parseInt(s, 10);
}
复制代码

As you can see, the method we called parseInt()returned an overloaded method:

public static int parseInt(String s, int radix) throws NumberFormatException {
    if (s == null) {
        throw new NumberFormatException("null");
    } else if (radix < 2) {
        throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX");
    } else if (radix > 36) {
        throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX");
    } else {
        boolean negative = false;
        int i = 0;
        int len = s.length();
        int limit = -2147483647;
        if (len <= 0) {
            throw NumberFormatException.forInputString(s);
        } else {
            char firstChar = s.charAt(0);
            if (firstChar < '0') {
                if (firstChar == '-') {
                    negative = true;
                    limit = -2147483648;
                } else if (firstChar != '+') {
                    throw NumberFormatException.forInputString(s);
                }

                if (len == 1) {
                    throw NumberFormatException.forInputString(s);
                }

                ++i;
            }

            int multmin = limit / radix;

            int result;
            int digit;
            for(result = 0; i < len; result -= digit) {
                digit = Character.digit(s.charAt(i++), radix);
                if (digit < 0 || result < multmin) {
                    throw NumberFormatException.forInputString(s);
                }

                result *= radix;
                if (result < limit + digit) {
                    throw NumberFormatException.forInputString(s);
                }
            }

            return negative ? result : -result;
        }
    }
}
复制代码

1. The first thing you see is that this method passes in two parameters, parseInt(String s, int radix), this can be based on the parameters passed in when it is called, , return parseInt(s, 10);and a blind guess smeans that it means to be converted into a numeric string, and radixEnglish is a radix Meaning, this should represent the base, that is, what base is the incoming string in? Is it correct? Let’s take a look below;

2. Here we first judge swhether the string is empty and the size of it. If the conditions are not met , an exception will be thrown, which is a digital format exception;radixNumberFormatException

if (s == null){
    throw new NumberFormatException("null");
} else if (radix < 2) {
    throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX");
} else if (radix > 36) {
    throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX");
} else {
复制代码

3. Then go down and perform a check on the length again.

int len = s.length();
if (len <= 0) {
    throw NumberFormatException.forInputString(s);
} else {
	...
}
复制代码

I only thought of a condition that would allow it to throw an exception,

Integer.parseInt("");
复制代码

operation result:

Exception in thread "main" java.lang.NumberFormatException: For input string: ""
	at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.base/java.lang.Integer.parseInt(Integer.java:662)
	at java.base/java.lang.Integer.parseInt(Integer.java:770)
复制代码

4. Next, it will detect what the first character is. If it is -, negativeset to true, indicating that this is a negative number, and limitset the boundary to the minimum boundary;

If not +, it means that the character is neither a number nor a qualitative symbol, so NumberFormatExceptionan exception is thrown;

If sthe length of the string is only 1, it means that it is not a number and does not meet the requirements, and NumberFormatExceptionan exception will be thrown;

++iThis is because if the first bit is a symbol, then appending numbers in subsequent loops will directly skip the first bit;

 char firstChar = s.charAt(0);
 if (firstChar < '0') {
     if (firstChar == '-') {
         negative = true;
         limit = -2147483648;
     } else if (firstChar != '+') {
         throw NumberFormatException.forInputString(s);
     }

     if (len == 1) {
         throw NumberFormatException.forInputString(s);
     }

     ++i;
 }
复制代码

5. Adjust the boundaries according to the hexadecimal system to prevent crossing the boundaries;

int multmin = limit / radix;
复制代码

6. Character.digit()Used to convert characters into integers of the corresponding base. If the character is not in the base, -1 will be returned. For example, the input character is 9, but the base is 2, then it does not match, and - will be returned. 1;

Then comes the calculation;

int result;
int digit;
for(result = 0; i < len; result -= digit) {
    digit = Character.digit(s.charAt(i++), radix);
    if (digit < 0 || result < multmin) {
        throw NumberFormatException.forInputString(s);
    }

    result *= radix;
    if (result < limit + digit) {
        throw NumberFormatException.forInputString(s);
    }
}
复制代码

7. Finally, judge whether it is a negative number to complete the conversion;

return negative ? result : -result;
复制代码

View the source code as usual:

public static Integer valueOf(String s, int radix) throws NumberFormatException {
    return parseInt(s, radix);
}

public static Integer valueOf(String s) throws NumberFormatException {
    return parseInt(s, 10);
}

@HotSpotIntrinsicCandidate
public static Integer valueOf(int i) {
    return i >= -128 && i <= Integer.IntegerCache.high ? Integer.IntegerCache.cache[i + 128] : new Integer(i);
}
复制代码

It can be seen valueOf(String s, int radix)that and valueOf(String s)are both directly called and returned to parseIntthe method, while valueOf(int i)is an automatic boxing intconverted into ;Integer

Next, if we explore it IntegerCache , we can see that this is Integera member inner class of . Let’s look at the source code:

private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer[] cache;
    static Integer[] archivedCache;

    private IntegerCache() {
    }

    static {
        int h = 127;
        String integerCacheHighPropValue = VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        int size;
        if (integerCacheHighPropValue != null) {
            try {
                size = Integer.parseInt(integerCacheHighPropValue);
                size = Math.max(size, 127);
                h = Math.min(size, 2147483518);
            } catch (NumberFormatException var6) {
            }
        }

        high = h;
        VM.initializeFromArchive(Integer.IntegerCache.class);
        size = high - -128 + 1;
        if (archivedCache == null || size > archivedCache.length) {
            Integer[] c = new Integer[size];
            int j = -128;

            for(int k = 0; k < c.length; ++k) {
                c[k] = new Integer(j++);
            }

            archivedCache = c;
        }

        cache = archivedCache;

        assert high >= 127;

    }
}
复制代码

The whole thing is to initialize an IntegerCache.cachearray. The array stores numbers between -128 and 127 as a cache. The source code first analyzes the length of the array and then assigns values ​​to the array;

In general, the three reconstruction valueOf()methods are still very similar:

  • Integer valueOf(int i): Returns an Integer instance representing the specified int value;
  • Integer valueOf(String s): Returns an Integer object that holds the value of the specified String;
  • Integer valueOf(String s, int radix): Returns an Integer object that holds the value extracted from the specified String when parsed using the base provided by the second parameter;

Guess you like

Origin blog.csdn.net/2301_76607156/article/details/130525592