The third chapter Java packaging class Byte, Short, Long source code analysis

Preface

Birds of a feather flock together. Similarity is one of the rules of the evolution of everything in the world. As a world, java is also full of many similarities. If you can put similar classes together, strip out their common characteristics, and reassemble these common characteristics into a new class, then this class is an abstract class.

狗按照不同的特点,可以分为很多种类。 
按色泽分类: 纯色狗、花色狗。
按大小分类:小狗、大狗。
按品种分类:田园犬、贵宾犬。
不论按什么特点分类,它们的公共特点都是四条腿、狗嘴、狗眼、狗鼻、狗耳朵、狗尾巴等等。
因此这些特点组成了一个狗的抽象类。

Similarity exists not only in the real world, but also in the java world.
The three packaging classes of Byte, Short, and Long analyzed today, they and Integer are part of the integral type in the basic data types, so they also have similarities. The difference is that the defined word length space is different, and the upper limit and lower limit are different. However, they all have the same meaning in JAVA, which is an integer value.

Byte, Short, Long packaging

Because they have the same meaning as Integer, most of their source code is exactly the same as Integer's source code. Therefore, analyzing Integer is equivalent to analyzing this type of source code.
In this article, I only do a comparative analysis with Integer, and do not explain the source code in detail. For detailed explanation of the source code, please refer to Chapter 2 "Integer Source Code Analysis of JAVA Packaging "
webpage address: "Integer Source Analysis of JAVA Packaging"

One, parseInt() comparative analysis

parseByte () y :

public static byte parseByte(String s, int radix)
    throws NumberFormatException {
    int i = Integer.parseInt(s, radix);
    if (i < MIN_VALUE || i > MAX_VALUE)		// MIN_VALUE:-127   MAX_VALUE:128  
        throw new NumberFormatException(
            "Value out of range. Value:\"" + s + "\" Radix:" + radix);
    return (byte)i;
}

parseShort() method:

public static short parseShort(String s, int radix)
    throws NumberFormatException {
    int i = Integer.parseInt(s, radix);
    if (i < MIN_VALUE || i > MAX_VALUE)   // MIN_VALUE:-32768   MAX_VALUE:32767
        throw new NumberFormatException(
            "Value out of range. Value:\"" + s + "\" Radix:" + radix);
    return (short)i;
}

As can be seen from the above two methods, since the upper and lower limits of short and byte are within the range of Integer expression, they directly call the Integer() method. The expression range of parseLong is greater than Integer, so it cannot be called directly. But its code is the same as Integer. The difference is that the quoted upper and lower limits have been changed to Long limits.

parseLong() method:

public static long parseLong(String s, int radix)
          throws NumberFormatException
{
    if (s == null) {
        throw new NumberFormatException("null");
    }

    if (radix < Character.MIN_RADIX) {
        throw new NumberFormatException("radix " + radix +
                                        " less than Character.MIN_RADIX");
    }
    if (radix > Character.MAX_RADIX) {
        throw new NumberFormatException("radix " + radix +
                                        " greater than Character.MAX_RADIX");
    }

    long result = 0;
    boolean negative = false;
    int i = 0, len = s.length();
    long limit = -Long.MAX_VALUE; // 这里调用的最大界限改为了Long的最大界限
    long multmin;
    int digit;

    if (len > 0) {
        char firstChar = s.charAt(0);
        if (firstChar < '0') { // Possible leading "+" or "-"
            if (firstChar == '-') {
                negative = true;
                limit = Long.MIN_VALUE;  // 这里调用的最小界限改为了Long的最小界限
            } else if (firstChar != '+')
                throw NumberFormatException.forInputString(s);

            if (len == 1) // Cannot have lone "+" or "-"
                throw NumberFormatException.forInputString(s);
            i++;
        }
        multmin = limit / radix;
        while (i < len) {
            // Accumulating negatively avoids surprises near MAX_VALUE
            digit = Character.digit(s.charAt(i++),radix);
            if (digit < 0) {
                throw NumberFormatException.forInputString(s);
            }
            if (result < multmin) {
                throw NumberFormatException.forInputString(s);
            }
            result *= radix;
            if (result < limit + digit) {
                throw NumberFormatException.forInputString(s);
            }
            result -= digit;
        }
    } else {
        throw NumberFormatException.forInputString(s);
    }
    return negative ? result : -result;
}

2. Comparative analysis of cache internal classes and valueOf()

ByteCache: This cache class caches all the values ​​that byte can represent in the internal class, that is, -128 to 127.

private static class ByteCache {
    private ByteCache(){}

    static final Byte cache[] = new Byte[-(-128) + 127 + 1];

    static {
        for(int i = 0; i < cache.length; i++)
            cache[i] = new Byte((byte)(i - 128));
    }
}

ShortCache: The cache limit of this cache class is only -128 to 127. The upper limit cannot be adjusted in the JVM like Integer.

private static class ShortCache {
    private ShortCache(){}

    static final Short cache[] = new Short[-(-128) + 127 + 1];

    static {
        for(int i = 0; i < cache.length; i++)
            cache[i] = new Short((short)(i - 128));
    }
}

LongCache: The cache limit of this cache class is the same, only -128 to 127. The upper limit cannot be adjusted in the JVM like Integer.

private static class LongCache {
    private LongCache(){}

    static final Long cache[] = new Long[-(-128) + 127 + 1];

    static {
        for(int i = 0; i < cache.length; i++)
            cache[i] = new Long(i - 128);
    }
}

The valueOf of Byte, Short, and Long is to first determine whether it is in the cache range, otherwise it will renew the NEW object. The principle is the same as that of Integer, so no code will be posted here.

Three, toString() comparative analysis

byte的toString()

public static String toString(byte b) {
    return Integer.toString((int)b, 10);
}

short的toString()

public static String toString(short s) {
    return Integer.toString((int)s, 10);
}

They are all called Integers, because their numerical expression ranges are all within the Integer range.

Long toString(): Basically the same as Integer. The difference is that the length of the array definition and the upper and lower bound calls are different.

public static String toString(long i, int radix) {
    if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
        radix = 10;
    if (radix == 10)
        return toString(i);
    char[] buf = new char[65];
    int charPos = 64;
    boolean negative = (i < 0);

    if (!negative) {
        i = -i;
    }

    while (i <= -radix) {
        buf[charPos--] = Integer.digits[(int)(-(i % radix))];
        i = i / radix;
    }
    buf[charPos] = Integer.digits[(int)(-i)];

    if (negative) {
        buf[--charPos] = '-';
    }

    return new String(buf, charPos, (65 - charPos));
}

to sum up:

It can be seen that the commonly used methods are similar to everything. For the integral part of the packaging class, in fact, only the Integer method needs to be studied, which is used most frequently. Other integral packaging classes are all extended from Integer. Have a high similarity. If there are errors in the above, please point out the judges.

Guess you like

Origin blog.csdn.net/weixin_43901067/article/details/104550103