Long源码解析-jdk1.8

334 阅读2分钟

Long 源码解析

  • 继承自 Number, Comparable
  • 属性 final long value
  • minValue ~ maxValue = (-2^63 ) ~ (2^63 -1)
  • 可类比Integer, Short; 但Float,Double 等没有Cache这一说 缓存 (-128~127)
  • 装箱: -128~127 自动拆箱, >127 || <-128 自动装箱

1. LongCache

  • 缓存 -128 ~ 127 的值, valueOf

    private static class LongCache {
            private LongCache(){}
            //缓存-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);
            }
        }
    
    
    

2. parseLong

/**
* s 字符串
* radix 字符串进制类型  范围 2~36, 对应字符串的进制
**/
public static long parseLong(String s, int radix)
            throws NumberFormatException
  {
      if (s == null) {
          throw new NumberFormatException("null");
      }
      // 2 进制 即 char x = '0' || '1' radix最小值为2
      if (radix < Character.MIN_RADIX) {
          throw new NumberFormatException("radix " + radix +
                                          " less than Character.MIN_RADIX");
      }
      // 36 因为可以在数值于字符串转换的范围是 0-9 a-z 共计 36
      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 multmin;
      int digit;

      if (len > 0) {
          char firstChar = s.charAt(0);
  	  //判定是否为负数
          if (firstChar < '0') { // Possible leading "+" or "-"
              if (firstChar == '-') {
  		//标识符 true 负数, false 正数
                  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++;
          }
          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;
  }

3. valueOf

/**
  * 注意返回值是Long
  **/
public static Long valueOf(String s, int radix) throws NumberFormatException {
        return Long.valueOf(parseLong(s, radix));
    }

/**
  * 注意返回值是Long, 默认是10进制
  **/
public static Long valueOf(String s) throws NumberFormatException
    {
        return Long.valueOf(parseLong(s, 10));
    }
	
/**
  * 注意返回值是Long, 其适用于 -128~127 范围内的数值型计算,其会自动拆箱
  * new Long(1)等同于 final long value = 1L;
  **/
public static Long valueOf(long l) {
        final int offset = 128;
        if (l >= -128 && l <= 127) { // will cache
            return LongCache.cache[(int)l + offset];
        }
        return new Long(l);
    }

4. 彩蛋

  • Long.parseLong, Long.valueOf的适用场景
  • a) 字符串转long数值型, 无论是采用 Long.valueOf,还是Long.parseLong 均可
  • b) 针对于包装类Long,用于对象的处理,采用Long.valueOf
  • c) 针对于-128~127的long数值型, 建议采用Long.valueOf,其次才是long 因为LongCache有对-128~127的缓存,是常量池的数据
  • d) 结论 针对于long的操作,无论是String, long, 还是Long 的场景,Long.valueof更是一种万金油的方法,同时兼顾了性能

5. Long的使用样例

  • 结果为True的场景

a) Long n1 = 124L; Long n2 = 124L; n1 == n2;

b) long n3 = 124L; Long n4 = 124L; n3 == n4; //自动拆箱

  • 结果为False的场景

a) Long n1 = 128L; Long n2 = 128L; n1 == n2;

b) long n3 = 128L; Long n4 = 128L; n3 == n4; //自动装箱

c) Long n5 = new Long(128); Long n6 = new Long(128); n5 == n6