JDK源码解析之【Long】类

6 篇文章 0 订阅 ¥9.90 ¥99.00

前言

今天来看看Long这个类的源码。

Long相关概念

Long是被final修饰的,因此该类不能被继承。另外它是long类的包装类。继承了抽象类Number,并且实现了Comparable接口,所以可以进行参数的比较。

Long 源码


package java.lang;

import jdk.internal.HotSpotIntrinsicCandidate;

import java.lang.annotation.Native;
import java.math.BigInteger;
import java.util.Objects;

import static java.lang.String.COMPACT_STRINGS;
import static java.lang.String.LATIN1;
import static java.lang.String.UTF16;
//Long是被final修饰的,因此该类不能被继承。另外它是long类的包装类。继承了抽象类Number,并且实现了Comparable接口,所以可以进行参数的比较。
public final class Long extends Number implements Comparable<Long> {
    
    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    @Native
    private static final long serialVersionUID = 4290774380558885855L;
    
    // 相当于long.class
    @SuppressWarnings("unchecked")
    public static final Class<Long> TYPE = (Class<Long>) Class.getPrimitiveClass("long");
    
    /**
     * long最小值 -2^63
     */
    @Native
    public static final long MIN_VALUE = 0x8000000000000000L; 
    
    /**
     * have, 2<sup>63</sup>-1.
     * long最大值 (2^63)-1
     */
    @Native
    public static final long MAX_VALUE = 0x7fffffffffffffffL; 
    
    /**
     *当前类型所占bit[位]数(Long类型占用8个字节,也就是64位)
     * @since 1.5
     */
    @Native
    public static final int SIZE = 64;
    /**
     *当前类型所占字节数(Long类型占8个字节)
     * 8 = 64 / 8
     * @since 1.8
     */
    public static final int BYTES = SIZE / Byte.SIZE;
    
   // 当前类包装的值
    private final long value; 
    
    // Long有参构造,传入long类型参数,用于创建Long对象
    @Deprecated(since = "9")
    public Long(long value) {
        this.value = value;
    }
    
    /**
     * Long有参构造,传入String类型参数,用于创建Long对象
     */
    @Deprecated(since = "9")
    public Long(String s) throws NumberFormatException {
        this.value = parseLong(s, 10);
    }
    /**
     * long类型转换为Long 类型.(装箱)
     * @since 1.5
     */
    @HotSpotIntrinsicCandidate
    public static Long valueOf(long l) {
        final int offset = 128;
        // 如果 -128 <= l <=127 直接从缓存中取出该对象,否则直接实例化
        if(l >= -128 && l<=127) {
            return LongCache.cache[(int) l + offset];
        }
        return new Long(l);
    }
    
   // 按10进制形式将字符串s解析为long值,随后再装箱
    public static Long valueOf(String s) throws NumberFormatException {
        return Long.valueOf(parseLong(s, 10));// 第二个参数表示10进制
    }
    
    // 按radix进制形式将字符串s解析为long值,随后再装箱
    public static Long valueOf(String s, int radix) throws NumberFormatException {
        return Long.valueOf(parseLong(s, radix));
    }
    
    /*
     * 将字符串nm解析为long,随后再装箱
     *
     * 采用哪种进制解析nm取决于nm的格式:
     * > 0x、0X、#开头,代表按16进制解析
     * > 0开头,代表按8进制解析
     * > 其他情形默认按10进制解析
     */
    public static Long decode(String nm) throws NumberFormatException {
        int radix = 10;
        int index = 0;
        boolean negative = false;
        Long result;
        
        if(nm.length() == 0)
            throw new NumberFormatException("Zero length string");
        char firstChar = nm.charAt(0);
        // Handle sign, if present
        if(firstChar == '-') {
            negative = true;
            index++;
        } else if(firstChar == '+')
            index++;
        
        // 判断该字符串位X进制格式
        if(nm.startsWith("0x", index) || nm.startsWith("0X", index)) {
            index += 2;
            radix = 16;
        } else if(nm.startsWith("#", index)) {
            index++;
            radix = 16;
        } else if(nm.startsWith("0", index) && nm.length()>1 + index) {
            index++;
            radix = 8;
        }
        
        if(nm.startsWith("-", index) || nm.startsWith("+", index))
            throw new NumberFormatException("Sign character in wrong position");
        
        try {
            result = Long.valueOf(nm.substring(index), radix);
            result = negative ? Long.valueOf(-result.longValue()) : result;
        } catch(NumberFormatException e) {
            String constant = negative ? ("-" + nm.substring(index)) : nm.substring(index);
            result = Long.valueOf(constant, radix);
        }
        return result;
    }
    
   /**
     * 重写父类(Number)方法,将Long值转换为byte类型
     */
    public byte byteValue() {
        return (byte) value;
    }
    
     /**
     * 重写父类(Number)方法,将Long值转换为short类型
     */
    public short shortValue() {
        return (short) value;
    } 
    /**
     * 重写父类(Number)方法,将Long值转换为int类型
     */
    public int intValue() {
        return (int) value;
    }
    
    /**
     * 重写父类(Number)方法,将Long值转换为long类型:拆箱
     */
    @HotSpotIntrinsicCandidate
    public long longValue() {
        return value;
    }
   /**
     * 重写父类(Number)方法,将Long值转换为float类型
     */
    public float floatValue() {
        return (float) value;
    }  
    
   /**
     *重写父类(Number)方法,将Long值转换为double类型
     */
    public double doubleValue() {
        return (double) value;
    }
    
    /*
     * 从系统属性中获取值,然后再装箱
     * 其中,nm为某个系统属性,val为备用值
     *
     * 比如:
     * System.setProperty("age", "20");
     * Long x = getLong("age", 25);
     * 如果属性age存在(被提前设置),x的值为20。
     * 如果属性age不存在,则x的值为备用值25。
     */
    public static Long getLong(String nm, Long val) {
        String v = null;
        try {
            v = System.getProperty(nm);
        } catch(IllegalArgumentException | NullPointerException e) {
        }
        if(v != null) {
            try {
                return Long.decode(v);
            } catch(NumberFormatException e) {
            }
        }
        return val;
    }
    
   // 从系统属性中获取值,然后再装箱。如果取不到值,选用val
    public static Long getLong(String nm, long val) {
        Long result = Long.getLong(nm, null);
        return (result == null) ? Long.valueOf(val) : result;
    }
    
    // 从系统属性中获取值,然后再装箱。如果取不到值,返回null
    public static Long getLong(String nm) {
        return getLong(nm, null);
    }
    
   /**
     * 按radix进制形式将字符串s解析为long值
     * parseLong("0", 10) returns 0L
     * parseLong("473", 10) returns 473L
     * parseLong("+42", 10) returns 42L
     * parseLong("-0", 10) returns 0L
     * parseLong("-FF", 16) returns -255L
     * parseLong("1100110", 2) returns 102L
     * parseLong("99", 8) throws a NumberFormatException
     * parseLong("Hazelnut", 10) throws a NumberFormatException
     * parseLong("Hazelnut", 36) returns 1356099454469L
     */
    public static long parseLong(String s, int radix) throws NumberFormatException {
        if(s == null) {
            throw new NumberFormatException("null");
        }
        
        if(radix<Character.MIN_RADIX) { // 进制转换约束下限,最小2进制
            throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX");
        }
        if(radix>Character.MAX_RADIX) {// 进制转换约束上限,最大36进制,因为10个数字+26个字母的限制
            throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX");
        }
        
        boolean negative = false;
        int i = 0, len = s.length();
        long limit = -Long.MAX_VALUE;
        
        if(len>0) {
            char firstChar = s.charAt(0);
            if(firstChar<'0') { // Possible leading "+" or "-"
                if(firstChar == '-') {
                    negative = true;
                    limit = Long.MIN_VALUE;
                } else if(firstChar != '+') {
                    throw NumberFormatException.forInputString(s);
                }
                
                if(len == 1) { // Cannot have lone "+" or "-"
                    throw NumberFormatException.forInputString(s);
                }
                i++;
            }
            long multmin = limit / radix;
            long result = 0;
            while(i<len) {
                // Accumulating negatively avoids surprises near MAX_VALUE
                int 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);
                }
                result -= digit;
            }
            return negative ? result : -result;
        } else {
            throw NumberFormatException.forInputString(s);
        }
    }
    
  // 按10进制形式将字符串s解析为long值
    public static long parseLong(String s) throws NumberFormatException {
        return parseLong(s, 10);
    }
    
    /**
     * 按radix进制形式将字符序列s的[beginIndex, endIndex)部分解析为long值
     * @since 9
     */
    public static long parseLong(CharSequence s, int beginIndex, int endIndex, int radix) throws NumberFormatException {
        s = Objects.requireNonNull(s);
        
        if(beginIndex<0 || beginIndex>endIndex || endIndex>s.length()) {
            throw new IndexOutOfBoundsException();
        }
        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");
        }
        
        boolean negative = false;
        int i = beginIndex;
        long limit = -Long.MAX_VALUE;
        
        if(i<endIndex) {
            char firstChar = s.charAt(i);
            if(firstChar<'0') { // Possible leading "+" or "-"
                if(firstChar == '-') {
                    negative = true;
                    limit = Long.MIN_VALUE;
                } else if(firstChar != '+') {
                    throw NumberFormatException.forCharSequence(s, beginIndex, endIndex, i);
                }
                i++;
            }
            if(i >= endIndex) { // Cannot have lone "+", "-" or ""
                throw NumberFormatException.forCharSequence(s, beginIndex, endIndex, i);
            }
            long multmin = limit / radix;
            long result = 0;
            while(i<endIndex) {
                // Accumulating negatively avoids surprises near MAX_VALUE
                int digit = Character.digit(s.charAt(i), radix);
                if(digit<0 || result<multmin) {
                    throw NumberFormatException.forCharSequence(s, beginIndex, endIndex, i);
                }
                result *= radix;
                if(result<limit + digit) {
                    throw NumberFormatException.forCharSequence(s, beginIndex, endIndex, i);
                }
                i++;
                result -= digit;
            }
            return negative ? result : -result;
        } else {
            throw new NumberFormatException("");
        }
    }
    
   /**
     * 按radix进制形式将无符号整型字符串s解析为有符号整型值
     * @since 1.8
     */
    public static long parseUnsignedLong(String s, int radix) throws NumberFormatException {
        if(s == null) {
            throw new NumberFormatException("null");
        }
        
        int len = s.length();
        if(len>0) {
            char firstChar = s.charAt(0);
            if(firstChar == '-') {
                throw new NumberFormatException(String.format("Illegal leading minus sign " + "on unsigned string %s.", s));
            } else {
                if(len<=12 || // Long.MAX_VALUE in Character.MAX_RADIX is 13 digits
                    (radix == 10 && len<=18)) { // Long.MAX_VALUE in base 10 is 19 digits
                    return parseLong(s, radix);
                }
                
                // No need for range checks on len due to testing above.
                long first = parseLong(s, 0, len - 1, radix);
                int second = Character.digit(s.charAt(len - 1), radix);
                if(second<0) {
                    throw new NumberFormatException("Bad digit at end of " + s);
                }
                long result = first * radix + second;
                
                int guard = radix * (int) (first >>> 57);
                if(guard >= 128 || (result >= 0 && guard >= 128 - Character.MAX_RADIX)) {

                    throw new NumberFormatException(String.format("String value %s exceeds " + "range of unsigned long.", s));
                }
                return result;
            }
        } else {
            throw NumberFormatException.forInputString(s);
       }
    }
    
  // 按10进制形式将无符号整型字符串s解析为有符号整型值
    public static long parseUnsignedLong(String s) throws NumberFormatException {
        return parseUnsignedLong(s, 10);
    }
    
    /*
     * 按radix进制形式将无符号整型字符序列s的[beginIndex, endIndex)部分解析为有符号整型值
     * @since 9
     */
    public static long parseUnsignedLong(CharSequence s, int beginIndex, int endIndex, int radix) throws NumberFormatException {
        s = Objects.requireNonNull(s);
        
        if(beginIndex<0 || beginIndex>endIndex || endIndex>s.length()) {
            throw new IndexOutOfBoundsException();
        }
        int start = beginIndex, len = endIndex - beginIndex;
        
        if(len>0) {
            char firstChar = s.charAt(start);
            if(firstChar == '-') {
                throw new NumberFormatException(String.format("Illegal leading minus sign " + "on unsigned string %s.", s.subSequence(start, start + len)));
            } else {
                if(len<=12 || // Long.MAX_VALUE in Character.MAX_RADIX is 13 digits
                    (radix == 10 && len<=18)) { // Long.MAX_VALUE in base 10 is 19 digits
                    return parseLong(s, start, start + len, radix);
                }
                
                // No need for range checks on end due to testing above.
                long first = parseLong(s, start, start + len - 1, radix);
                int second = Character.digit(s.charAt(start + len - 1), radix);
                if(second<0) {
                    throw new NumberFormatException("Bad digit at end of " + s.subSequence(start, start + len));
                }
                long result = first * radix + second;
                
                /*
                 * Test leftmost bits of multiprecision extension of first*radix
                 * for overflow. The number of bits needed is defined by
                 * GUARD_BIT = ceil(log2(Character.MAX_RADIX)) + 1 = 7. Then
                 * int guard = radix*(int)(first >>> (64 - GUARD_BIT)) and
                 * overflow is tested by splitting guard in the ranges
                 * guard < 92, 92 <= guard < 128, and 128 <= guard, where
                 * 92 = 128 - Character.MAX_RADIX. Note that guard cannot take
                 * on a value which does not include a prime factor in the legal
                 * radix range.
                 */
                int guard = radix * (int) (first >>> 57);
                if(guard >= 128 || (result >= 0 && guard >= 128 - Character.MAX_RADIX)) {
                    /*
                     * For purposes of exposition, the programmatic statements
                     * below should be taken to be multi-precision, i.e., not
                     * subject to overflow.
                     *
                     * A) Condition guard >= 128:
                     * If guard >= 128 then first*radix >= 2^7 * 2^57 = 2^64
                     * hence always overflow.
                     *
                     * B) Condition guard < 92:
                     * Define left7 = first >>> 57.
                     * Given first = (left7 * 2^57) + (first & (2^57 - 1)) then
                     * result <= (radix*left7)*2^57 + radix*(2^57 - 1) + second.
                     * Thus if radix*left7 < 92, radix <= 36, and second < 36,
                     * then result < 92*2^57 + 36*(2^57 - 1) + 36 = 2^64 hence
                     * never overflow.
                     *
                     * C) Condition 92 <= guard < 128:
                     * first*radix + second >= radix*left7*2^57 + second
                     * so that first*radix + second >= 92*2^57 + 0 > 2^63
                     *
                     * D) Condition guard < 128:
                     * radix*first <= (radix*left7) * 2^57 + radix*(2^57 - 1)
                     * so
                     * radix*first + second <= (radix*left7) * 2^57 + radix*(2^57 - 1) + 36
                     * thus
                     * radix*first + second < 128 * 2^57 + 36*2^57 - radix + 36
                     * whence
                     * radix*first + second < 2^64 + 2^6*2^57 = 2^64 + 2^63
                     *
                     * E) Conditions C, D, and result >= 0:
                     * C and D combined imply the mathematical result
                     * 2^63 < first*radix + second < 2^64 + 2^63. The lower
                     * bound is therefore negative as a signed long, but the
                     * upper bound is too small to overflow again after the
                     * signed long overflows to positive above 2^64 - 1. Hence
                     * result >= 0 implies overflow given C and D.
                     */
                    throw new NumberFormatException(String.format("String value %s exceeds " + "range of unsigned long.", s.subSequence(start, start + len)));
                }
                return result;
            }
        } else {
            throw NumberFormatException.forInputString("");
        }
    }
    
    // 按10进制返回当前long的值
    public String toString() {
        return toString(value);
    }
    

    // 按10进制返回i的值
    public static String toString(long i) {
        int size = stringSize(i);
        if(COMPACT_STRINGS) {
            byte[] buf = new byte[size];
            getChars(i, size, buf);
            return new String(buf, LATIN1);
        } else {
            byte[] buf = new byte[size * 2];
            StringUTF16.getChars(i, size, buf);
            return new String(buf, UTF16);
        }
    }
    
    // 按radix进制返回i的值
    public static String toString(long i, int radix) {
        // 进制转换约束下限,最小2进制.进制转换约束上限,最大36进制,因为10个数字+26个字母的限制
        if(radix<Character.MIN_RADIX || radix>Character.MAX_RADIX) {
            // 默认为10进制
            radix = 10;
        }
    
        if(radix == 10) {
            return toString(i);
        }
    
        if(COMPACT_STRINGS) {
            byte[] buf = new byte[65];
            int charPos = 64;
            boolean negative = (i<0);
        
            if(!negative) {
                i = -i;
            }
            
            while(i<=-radix) {
                buf[charPos--] = (byte) Integer.digits[(int) (-(i % radix))];
                i = i / radix;
            }
            buf[charPos] = (byte) Integer.digits[(int) (-i)];
            
            if(negative) {
                buf[--charPos] = '-';
            }
            return StringLatin1.newString(buf, charPos, (65 - charPos));
        }
    
        return toStringUTF16(i, radix);
    }  
    
   /**
     * 按2进制返回i的无符号值
     * @since 1.0.2
     */
    public static String toBinaryString(long i) {
        return toUnsignedString0(i, 1);// 2^1 = 2进制
    }
    
   /**
     * 按8进制返回i的无符号值
     * @since 1.0.2
     */
    public static String toOctalString(long i) {
        return toUnsignedString0(i, 3);// 2^3 = 2进制
    }
    
    /**
     * 按10进制返回i的无符号值
     * @since 1.8
     */
    public static String toUnsignedString(long i) {
        return toUnsignedString(i, 10);
    }
    
    /**
     * 按16进制返回i的无符号值
     * @since 1.0.2
     */
    public static String toHexString(long i) {
        return toUnsignedString0(i, 4);// 2^4 = 16进制
    }
    
    /**
     * 按radix进制返回i的无符号值
     * @since 1.8
     */
    public static String toUnsignedString(long i, int radix) {
        if(i >= 0) {
            return toString(i, radix);
        }
    
        switch(radix) {
            case 2:
                return toBinaryString(i);
        
            case 4:
                return toUnsignedString0(i, 2);
        
            case 8:
                return toOctalString(i);
        
            case 10:
                long quot = (i >>> 1) / 5;
                long rem = i - quot * 10;
                return toString(quot) + rem;
        
            case 16:
                return toHexString(i);
        
            case 32:
                return toUnsignedString0(i, 5);
        
            default:
                return toUnsignedBigInteger(i).toString(radix);
        }
    }
    
   /**
     * 按2^shift进制返回val的无符号值
     */
    static String toUnsignedString0(long val, int shift) {
        // assert shift > 0 && shift <=5 : "Illegal shift value";
        int mag = Long.SIZE - Long.numberOfLeadingZeros(val);
        int chars = Math.max(((mag + (shift - 1)) / shift), 1);
    
        if(COMPACT_STRINGS) {
            byte[] buf = new byte[chars];
            formatUnsignedLong0(val, shift, buf, 0, chars);
            return new String(buf, LATIN1);
        } else {
            byte[] buf = new byte[chars * 2];
            formatUnsignedLong0UTF16(val, shift, buf, 0, chars);
            return new String(buf, UTF16);
        }
    }
    
   // 按radix进制返回i的无符号值,UTF16版本
    private static String toStringUTF16(long i, int radix) {
        byte[] buf = new byte[65 * 2];
        int charPos = 64;
        boolean negative = (i<0);
        if(!negative) {
            i = -i;
        }
        while(i<=-radix) {
            StringUTF16.putChar(buf, charPos--, Integer.digits[(int) (-(i % radix))]);
            i = i / radix;
        }
        StringUTF16.putChar(buf, charPos, Integer.digits[(int) (-i)]);
        if(negative) {
            StringUTF16.putChar(buf, --charPos, '-');
        }
        return StringUTF16.newString(buf, charPos, (65 - charPos));
    }
    
     // 将数字0到9分别存储为对应的ANSI码,'\0'存储为数字0。byte[]/LATIN1版本。参见Integer#formatUnsignedInt
    static void formatUnsignedLong0(long val, int shift, byte[] buf, int offset, int len) {
        int charPos = offset + len;
        int radix = 1 << shift;
        int mask = radix - 1;
        do {
            buf[--charPos] = (byte) Integer.digits[((int) val) & mask];
            val >>>= shift;
        } while(charPos>offset);
    }
    
   // 将数字0到9分别存储为对应的ANSI码,'\0'存储为数字0。byte[]/UTF16版本。参见Integer#formatUnsignedInt
    private static void formatUnsignedLong0UTF16(long val, int shift, byte[] buf, int offset, int len) {
        int charPos = offset + len;
        int radix = 1 << shift;
        int mask = radix - 1;
        do {
            StringUTF16.putChar(buf, --charPos, Integer.digits[((int) val) & mask]);
            val >>>= shift;
        } while(charPos>offset);
    }
    
     /**
     * 统计整数i中包含的符号数量(包括负号),为转为字符串做准备
     * 比如stringSize(12345)返回5,stringSize(-12345)返回6
     */
    static int stringSize(long x) {
        int d = 1;
        if(x >= 0) {
            d = 0; // 如果是正数 d=0
            x = -x; // 如果是正数 x变为-x  在下面 x>p做准备
        }// 如果是负数,d=1,那么就可以把负号也统计进来
        long p = -10;
        for(int i = 1; i<19; i++) {//这里之所以循环19次,是因为long的最大值9_223_372_036_854_775_807为19位
            if(x>p)// 此时x永远为负数,p也是负数且每次扩大一位,所以当满足x>p的时候,返回i+d即可得到符号数量
                return i + d;
            p = 10 * p;// 每次*10,表示增加一位
        }
        return 19 + d;// 只有当x处于19位长度才满足该条件
    }   
    
    /**
     * 将整数i中包含的符号转为byte存入buf
     */
    static int getChars(long i, int index, byte[] buf) {
        long q;
        int r;
        int charPos = index;
        
        boolean negative = (i<0);
        if(!negative) {
            i = -i;
        }
        
        // Get 2 digits/iteration using longs until quotient fits into an int
        while(i<=Integer.MIN_VALUE) {
            q = i / 100;
            r = (int) ((q * 100) - i);
            i = q;
            buf[--charPos] = Integer.DigitOnes[r];
            buf[--charPos] = Integer.DigitTens[r];
        }
        
        // Get 2 digits/iteration using ints
        int q2;
        int i2 = (int) i;
        while(i2<=-100) {
            q2 = i2 / 100;
            r = (q2 * 100) - i2;
            i2 = q2;
            buf[--charPos] = Integer.DigitOnes[r];
            buf[--charPos] = Integer.DigitTens[r];
        }
        
        // We know there are at most two digits left at this point.
        q2 = i2 / 10;
        r = (q2 * 10) - i2;
        buf[--charPos] = (byte) ('0' + r);
        
        // Whatever left is the remaining digit.
        if(q2<0) {
            buf[--charPos] = (byte) ('0' - q2);
        }
        
        if(negative) {
            buf[--charPos] = (byte) '-';
        }
        return charPos;
    }
    
    /**
     * 将当前long转换为无符号形式,用BigInteger存储
     */
    private static BigInteger toUnsignedBigInteger(long i) {
        if(i >= 0L)
            return BigInteger.valueOf(i);
        else {
            int upper = (int) (i >>> 32);
            int lower = (int) i;
            
            // return (upper << 32) + lower
            return (BigInteger.valueOf(Integer.toUnsignedLong(upper))).shiftLeft(32).
                add(BigInteger.valueOf(Integer.toUnsignedLong(lower)));
        }
    }
    
        
    /**
     *比较两个long类型值的大小(按自然顺序比较)
     * @since 1.7
     */
    public static int compare(long x, long y) {
        return (x<y) ? -1 : ((x == y) ? 0 : 1);
    }
    
    /**
     *   比较两个Long(按自然顺序比较)
     * @since 1.2
     */
    public int compareTo(Long anotherLong) {
        return compare(this.value, anotherLong.value);
    }
    
    /**
     *以无符号形式比较两个long(按自然顺序比较)
     * @since 1.8
     */
    public static int compareUnsigned(long x, long y) {
        // 在这里对x、y都和Long的最小值相加。
        // 所以如果x、y是负数,那么和最小值相加后就会导致数据溢出,从而结果会在 MIN_VALUE <= n <= MAX_VALUE 范围区间内形成闭环
        return compare(x + MIN_VALUE, y + MIN_VALUE);
    }
    
    /**
     *返回long类型转化为二进制之后1的个数
     * @since 1.5
     */
    @HotSpotIntrinsicCandidate
    public static int bitCount(long i) {
        //1.求出i对应的二进制数的每两位之和,比如(01)(11)(10)(00)-->(01)(10)(01)(00)
        i = i - ((i >>> 1) & 0x5555555555555555L);
        //2.求出(1.)中i对应的二进制数的每四位之和,比如(0110)(0001)(1001)(1001) -->(0010)(0001)(0010)(0010)
        i = (i & 0x3333333333333333L) + ((i >>> 2) & 0x3333333333333333L);
        //3.同上求出(2.)中i的二进制数的每八位之和。
        i = (i + (i >>> 4)) & 0x0f0f0f0f0f0f0f0fL;
        //4.同上求出(3.)中i的二进制数的每十六位之和。
        i = i + (i >>> 8);
        //5.同上求出(4.)中i的二进制数的每三十二位之和
        i = i + (i >>> 16);
        //6.同上求出(5.)中i的二进制数的每六十四位之和。
        i = i + (i >>> 32);
        //1的个数最多也不会超过64个,所以只取最后7位即可。
        return (int) i & 0x7f;
    }
    
    /**
     * 循环左移,也就是将i向左移动distance位,
     * 当i的移位到达了最高位还没有够distance,那么移位的数就去低位开头,继续移位。
     * 所以叫做循环移位。distance可以为负
     * @since 1.5
     */
    public static long rotateLeft(long i, int distance) {
        //  <<表示左移移,不分正负数,低位补0;
        //  >>>表示无符号右移,也叫逻辑右移,即若该数为正,则高位补0,而若该数为负数,则右移后高位同样补0
        // | 表示 按位或。只要对应的二个二进位有一个为1时,结果位就为1。当参与运算的是负数时,参与两个数均以补码出现。
        // 补充:如果i为负数,那么需要对给该值进行反码,补码后再去移位

        // i =1  distance=2
        // i << distance) 表示 1 左移两位
        // i >>> -distance) 表示 1 无符号右移 ?位
        return (i << distance) | (i >>> -distance);
    }
    
    /**
     * 循环右移,也就是将i向右移动distance位,
     * 当i的移位到达了最低位还没有够distance,那么移位的数就去高位开头,继续移位。
     * 所以叫做循环移位。distance可以为负
     *  @since 1.5
     */
    public static long rotateRight(long i, int distance) {
        return (i >>> distance) | (i << -distance);
    }
    
   /**
     *  把i转化为二进制数,然后再把这个二进制数反转,
     *  参考文章:https://blog.csdn.net/songylwq/article/details/9015581
     * @since 1.5
     */
    public static long reverse(long i) {
        // HD, Figure 7-1
        i = (i & 0x5555555555555555L) << 1 | (i >>> 1) & 0x5555555555555555L;
        i = (i & 0x3333333333333333L) << 2 | (i >>> 2) & 0x3333333333333333L;
        i = (i & 0x0f0f0f0f0f0f0f0fL) << 4 | (i >>> 4) & 0x0f0f0f0f0f0f0f0fL;
        
        return reverseBytes(i);
    }
    
   /**
     * 判断i的正负。遇到负数返回-1,正数返回1,0返回0。
     *
     * 如果i是正数,那么i >> 63肯定为0,-i为负数,-i >>> 63无符号右移,肯定为1,所以结果为1。
     * 当i为0的时候结果为0,这个就不在分析。当i为负数的时候,i >> 63结果为……1111(共64个1)
     * ,-i >>> 63无论结果是什么,最终结果都是……1111(64个1),他是-1的补码,所以结果为-1。
     * 
     * 而为什么移位数是63?是因为Long类型占用8个字节,64位,移位63位后首位就是符号位了
     * @since 1.5
     */
    public static int signum(long i) {
        return (int) ((i >> 63) | (-i >>> 63));
    }
    
     /**
     *以字节为单位逆置字节顺序
     * @since 1.5
     */
    @HotSpotIntrinsicCandidate
    public static long reverseBytes(long i) {
        i = (i & 0x00ff00ff00ff00ffL) << 8 | (i >>> 8) & 0x00ff00ff00ff00ffL;
        return (i << 48) | ((i & 0xffff0000L) << 16) | ((i >>> 16) & 0xffff0000L) | (i >>> 48);
    }
    
   /**
     * 返回二进制位中开头连续的0的个数(把int值i表示为二进制形式)
     * @since 1.5
     */
    @HotSpotIntrinsicCandidate
    public static int numberOfLeadingZeros(long i) {
        int x = (int) (i >>> 32);// long为64位,无符号右移32(Integer为32位)位后.
        // 由于高位补0,即补32个零,为了调用下面的Integer的方法做准备
        // 如果此时x==0 ,则返回 32 + 32 = 64,否则调用Integer.numberOfLeadingZeros(x)返回具体的个数
        return x == 0 ? 32 + Integer.numberOfLeadingZeros((int) i) : Integer.numberOfLeadingZeros(x);
    }
    
    /**
     * 返回二进制位中末尾连续的0的个数(把int值i表示为二进制形式)
     * 基于二分查找
     * @since 1.5
     */
    @HotSpotIntrinsicCandidate
    public static int numberOfTrailingZeros(long i) {
        // HD, Figure 5-14
        int x, y;
        if(i == 0)
            return 64;// long为64位
        int n = 63;
        y = (int) i;
        if(y != 0) {
            n = n - 32;
            x = y;
        } else
            x = (int) (i >>> 32);
        y = x << 16;
        if(y != 0) {
            n = n - 16;
            x = y;
        }
        y = x << 8;
        if(y != 0) {
            n = n - 8;
            x = y;
        }
        y = x << 4;
        if(y != 0) {
            n = n - 4;
            x = y;
        }
        y = x << 2;
        if(y != 0) {
            n = n - 2;
            x = y;
        }
        return n - ((x << 1) >>> 31);
    }
    
   /**
     * 该方法返回i的二进制中最高位的1,其他全为0的值。
     * 比如i=10时,二进制即为1010,最高位的1,其他为0,则是1000。
     * 比如i=2时,二进制即为0010,最高位的1,其他为0,则是0010。
     * 比如i=3时,二进制即为0011,最高位的1,其他为0,则是0010 :2
     * 如果i=0,则返回0。
     * 如果i为负数则固定返回Long.MIN_VALUE,因为负数的最高位一定是1,即有1000,0000,0000,0000,0000,0000,0000,0000。
     * 参考:https://www.jb51.net/article/127763.htm
     * @since 1.5
     */
    public static long highestOneBit(long i) {
        return i & (MIN_VALUE >>> numberOfLeadingZeros(i));
    }
    
    /**
     * 该方法返回i的二进制中最低位1,其他全为0的值。
     * 这个操作较简单,先取负数,这个过程需要对正数的i取反码然后再加1,得到的结果和i进行与操作,刚好就是最低位1其他为0的值了。
     *  比如i=2时,二进制即为000...0010,-2的取反补码后1111 ... 1110,  000...0010 & 1111 ... 1110 = 000...0010 = 2
     *  比如i=3时,二进制即为000...0011,-3的取反补码后1111 ... 1101,   000...0011 & 1111 ... 1101 = 000...0001 = 1
     *  比如i=10时,二进制即为000...1010,-10的取反补码后1111 ... 0110, 000...1010 & 1111 ... 0110 = 000...0010 = 2
     * 参考:https://www.jb51.net/article/127763.htm
     * @since 1.5
     */
    public static long lowestOneBit(long i) {
        // & 表示 按位与 只有对应的两个二进位都为1时,结果位才为1。参与运算的两个数均以补码出现。
        return i & -i;
    }
    
    /**
     *返回 a + b 的值
     * @since 1.8
     */
    public static long sum(long a, long b) {
        return a + b;
    }
    /**
     * 调用Math.max(a, b)方法,返回两数中最大的一个
     * @since 1.8
     */
    public static long max(long a, long b) {
        return Math.max(a, b);
    }
    
    /**
     * 调用Math.min(a, b)方法,返回两数中最大的一个
     * @since 1.8
     */
    public static long min(long a, long b) {
        return Math.min(a, b);
    }
    
    /**
     * 除法运算。计算前需要先将两个long值转换为无符号形式
     * @param dividend  被除数
     * @param divisor   除数
     *  @since 1.8
     */
    public static long divideUnsigned(long dividend, long divisor) {
        if(divisor<0L) { // signed comparison
            // Answer must be 0 or 1 depending on relative magnitude of dividend and divisor.
            return (compareUnsigned(dividend, divisor))<0 ? 0L : 1L;
        }
        
        if(dividend>0) { 
            //  被除数和除数都大于0
            return dividend / divisor;
        } else {
            /*
             * For simple code, leveraging BigInteger.
             * Longer and faster code written directly in terms of operations on longs is possible;
             * see "Hacker's Delight" for divide and remainder algorithms.
             */
            return toUnsignedBigInteger(dividend).divide(toUnsignedBigInteger(divisor)).longValue();
        }
    }
    
   /**
     * 取余运算。计算前需要先将两个long值转换为无符号形式
     * @since 1.8
     */
    public static long remainderUnsigned(long dividend, long divisor) {
        if(dividend>0 && divisor>0) { // signed comparisons
            return dividend % divisor;
        } else {
            if(compareUnsigned(dividend, divisor)<0) { // Avoid explicit check for 0 divisor
                return dividend;
            } else {
                return toUnsignedBigInteger(dividend).remainder(toUnsignedBigInteger(divisor)).longValue();
            }
        }
    }
    
   /**
     *返回 Long 的哈希码
     * @since 1.8
     */
    public static int hashCode(long value) {
       // 首先将long型值无符号右移32位,再和原来的值进行异或运算,最后返回int类型值。
        // 异或运算规则:(参考:https://www.cnblogs.com/tmdsleep/p/9933647.html)
        // 0^0 = 0
        // 1^0 = 1
        // 0^1 = 1
        // 1^1 = 0
        return (int) (value ^ (value >>> 32));
    }
    
        /**
     * 将Long类型转换为long类型.然后用==比较值是否相等。
     *  如果不是obj不是Long类型,则直接返回不相等
     */
    public boolean equals(Object obj) {
        if(obj instanceof Long) {
            return value == ((Long) obj).longValue();
        }
        return false;
    }
    
        // Long缓存区间,缓存了-128~127之间的Long对象
    private static class LongCache {
        // 创建256个Long对象数组,用来缓存-128~127之间的对象
        static final Long cache[] = new Long[-(-128) + 127 + 1];
        
        static {
            for(int i = 0; i<cache.length; i++)
                cache[i] = new Long(i - 128);
        }
        
        private LongCache() {
        }
    }

Long源码测试

1.取值范围测试
@Test
public void test(){
    Long max = 9223372036854775807L;
    //  Long max = 9223372036854775808L; // 超出范围 编译报错
    Long min = -9223372036854775808L;
    //  Long min = -9223372036854775809L; //超出范围 编译报错
    System.out.println("Long的最大值:" + Long.MAX_VALUE);// (2^63)-1 = 9223372036854775807
    System.out.println("Long的最小值:" + Long.MIN_VALUE);// -(2^63) = -9223372036854775808

    System.out.println("Long所占用的位数:" + Long.SIZE);// 64
    System.out.println("Long所占用的字节数:" + Long.BYTES);// 8
}


2. public static Long decode(String nm)方法测试
@Test
public void testdecode(){
    // 说明:计算机输出的结果默认为10进制

    // 将十进制1 转为long,在装箱转为Long
    System.out.println(Long.decode("1"));// 结果:1
    // 将八进制031 转为long,在装箱转为Long
    System.out.println(Long.decode("031"));//结果:25
    // 将十六进制0xf 转为long,在装箱转为Long
    System.out.println(Long.decode("0xf"));// 结果:15
    // 将十进制21474836488 转为int,在转为int
    System.out.println(Long.decode("9223372036854775808L"));// 结果:java.lang.NumberFormatException: For input string: "9223372036854775808L" (9223372036854775808L超出了long取值范围)
}
3. public static Long getLong(String nm, Long val)方法测试

@Test
public void testgetLong(){
    // 从系统属性中获取值,如果获取不到则使用默认值。然后再装箱
    System.out.println(Long.getLong("age",10L));// 结果:10L
    // 从系统属性中获取值,然后再装箱.,如果取不到,则返回null
    System.out.println(Long.getLong("age"));// 结果:10L
    // 先向系统赋值,在获取
    System.setProperty("no","1");
    System.out.println(Long.getLong("no"));// 结果:1
}

4. public static String toString(long i)方法测试
@Test
public void testtoString(){
    System.out.println(Long.toString(4));// 4
    System.out.println(Long.toString(-4));// -4
    // 以2进制形式输出4
    System.out.println(Long.toString(4,2));// 100
    // 以2进制形式输出-4
    System.out.println(Long.toString(-4,2));// -100
    // 以4进制形式输出4
    System.out.println(Long.toString(4,4));// 10
    // 以4进制形式输出-4
    System.out.println(Long.toString(-4,4));// -10
}
5. static int stringSize(long x)方法测试
@Test
public void teststringSize(){
    //统计整数i中包含的符号数量(包括负号),为转为字符串做准备
   long x = Long.MAX_VALUE;
   System.out.println(stringSize(x));// 19
    System.out.println(stringSize(-123l));// 4
}

static int stringSize(long x) {
    int d = 1;
    if(x >= 0) {
        d = 0;
        x = -x;
    }
    long p = -10;
    for(int i = 1; i<19; i++) {//这里之所以循环19次,是因为long的最大值9_223_372_036_854_775_807为19位
        if(x>p)
            return i + d;
        p = 10 * p;
    }
    return 19 + d;// 只有当x处于19位长度才满足该条件
}
6. public static int compare(int x, int y)方法测试
@Test
public void testcompare(){
    // 比较两个int(按自然顺序比较)
    // (x < y) ? -1 : ((x == y) ? 0 : 1);
   System.out.println(Long.compare(-5,3));// -1
    System.out.println(Long.compare(3,3));// 0
    System.out.println(Long.compare(5,3));// 1
}
7.public static int compareUnsigned(long x, long y)方法测试
@Test
public void testcompareUnsigned(){
    // 以无符号形式比较两个int(按自然顺序比较)
    // 在这里对x、y都和Long的最小值相加。
    // 所以如果x、y是负数,那么和最小值相加后就会导致数据溢出,从而结果会在 MIN_VALUE <= n <= MAX_VALUE 范围区间内形成闭环
    //   return compare(x + MIN_VALUE, y + MIN_VALUE);
    System.out.println(Long.compareUnsigned(-1,3));// -1 + Long.MIN_VALUE=9223372036854775807 所以结果为1
    System.out.println(Long.compareUnsigned(-5,-3));// -5 + Long.MIN_VALUE=9223372036854775803,-3 + Long.MIN_VALUE=9223372036854775805 所以结果为-1

    System.out.println(Long.compareUnsigned(3,3));// 0
    System.out.println(Long.compareUnsigned(5,3));// 1

}
8.public static int bitCount(long i)方法测试
@Test
public void testbitCount(){
    //返回int类型转化为二进制之后1的个数
    System.out.println(Long.bitCount(1));// 01 ——> 1
    System.out.println(Long.bitCount(2));// 10 ——> 1
    System.out.println(Long.bitCount(10));// 1010  ——> 2
}
9.public static int signum(long i)方法测试
@Test
public void testsignum(){
    // 判断i的正负。遇到负数返回-1,正数返回1,0返回0。
    System.out.println(Long.signum(1));// 1
    System.out.println(Long.signum(0));// 0
    System.out.println(Long.signum(-2));// -1
}
10.public static int numberOfLeadingZeros(long i)方法测试
@Test
public void testnumberOfLeadingZeros(){
    // 计算 i 的二进制从头开始有多少个连续的 0.(Long为64位)

    // 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001  = 63
    System.out.println(Long.numberOfLeadingZeros(1));
    // 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000  = 64
    System.out.println(Long.numberOfLeadingZeros(0));
    // 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0010  = 62
    System.out.println(Long.numberOfLeadingZeros(2));
}
11.public static int numberOfTrailingZeros(long i)方法测试
@Test
public void testnumberOfTrailingZeros(){
    // 计算 i 的二进制从末尾开始有多少个连续的 0 .(Long为64位)

    // 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001  = 0
    System.out.println(Long.numberOfTrailingZeros(1));
    // 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000  = 64
    System.out.println(Long.numberOfTrailingZeros(0));
    // 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0010  = 1
    System.out.println(Long.numberOfTrailingZeros(2));
}
12.public static long highestOneBit(long i)方法测试
@Test
public void highestOneBit(){
  // 该方法返回i的二进制中最高位的1,其他全为0的值。
  // i=2时,二进制即为0000 ... 0010,最高位的1,其他为0,则是0010 : 2
   System.out.println(Long.highestOneBit(2));
  // i=3时,二进制即为0000 ... 0011,最高位的1,其他为0,则是0010 : 2
   System.out.println(Long.highestOneBit(3));
   //i=10时,二进制即为0000 ... 1010,最高位的1,其他为0,则是1000 :8
   System.out.println(Long.highestOneBit(10));

   // 比如i未负数时,固定返回Long.MIN_VALUE
   System.out.println(Long.highestOneBit(-10));
   System.out.println(Long.highestOneBit(-2));
}
13.public static long lowestOneBit(long i)方法测试
@Test
public void lowestOneBit(){
   // 该方法返回i的二进制中最低位1,其他全为0的值。

    //  i & -i;
    // 比如i=2时,二进制即为000...0010,-2的取反补码后1111 ... 1110,  000...0010 & 1111 ... 1110 = 000...0010 = 2
    System.out.println(Long.lowestOneBit(2));
    //比如i=3时,二进制即为000...0011,-3的取反补码后1111 ... 1101,   000...0011 & 1111 ... 1101 = 000...0001 = 1
    System.out.println(Long.lowestOneBit(3));
    //比如i=10时,二进制即为000...1010,-10的取反补码后1111 ... 0110, 000...1010 & 1111 ... 0110 = 000...0010 = 2
    System.out.println(Long.lowestOneBit(10));
}
14.计算方法测试
@Test
public void test2(){
    // 获取两数之和
    System.out.println(Long.sum(-1, -20)); // -21
    // 获取两个值中最大的一个
    System.out.println(Long.max(-1, -20)); // -1
    // 获取两个值中最小的一个
    System.out.println(Long.min(-1, -20)); // -20
    // 获取两个值相除的结果
    System.out.println(Long.divideUnsigned(4, 2)); // 2
    // 获取两个值取余的结果
    System.out.println(Long.remainderUnsigned(35, 3)); // 2
}
15.public boolean equals(Object obj)方法测试

@Test
public void test3(){
    // 测试值相等(要考虑缓存区间-128-127)
    //  1.取值在[-128, 127]区间内,值相同,则相同,结果为true,因为使用的是同一个对象
    //  2.取值在[-128, 127]区间外,即(-∞, -128) ∪(127, +∞),值相同,但对象引用不同,结果为false;
    // 3.两个变量其中之一或均使用new关键字赋值时,如Long i1 = new Long(?); Long i2 = new Long(?);则都是两个不同的对象
    Long a = 1L;
    Long b = 1L;
    System.out.println("a ==b : " + (a == b));// true
    System.out.println("a.equals(b): " + (a.equals(b)));// true

    Long  c = 128L;
    Long  d = 128L;
    System.out.println("c ==b : " + (c == d));// false
    System.out.println("c.equals(d): " + (c.equals(d)));// true

    Long e = new Long(1L);
    Long f = new Long(1L);
    System.out.println("e ==f : " + (e == f));// false
    System.out.println("e.equals(f): " + (e.equals(f)));// true
}

重要总结:
因为Long存在缓存区间,因此在[-128,127]之间都会使用同一个对象(new Long除外),因此Long类型只能用equals()方法进行比较值相等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tomatocc

赏杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值