美文网首页程序员
JDK源码分析 Integer

JDK源码分析 Integer

作者: 被称为L的男人 | 来源:发表于2017-08-06 19:32 被阅读99次

说明

对于JDK源码分析的文章,仅仅记录我认为重要的地方。源码的细节实在太多,不可能面面俱到地写清每个逻辑。所以我的JDK源码分析,着重在JDK的体系架构层面,具体源码可以参考:http://www.cnblogs.com/skywang12345/category/455711.html

Integer 说明

The Integer class wraps a value of the primitive type int in an object. An object of type Integer contains a single field whose type is int.

In addition, this class provides several methods for converting an int to a String and a String to an int, as well as other constants and methods useful when dealing with an int.

Number 接口

其继承了Number接口,能够转换成 int, long, float, double, byte, short等类型。

继承了Number接口的类,还有:AtomicInteger, AtomicLong, BigDecimal, BigInteger, Byte, Double, DoubleAccumulator, DoubleAdder, Float, Integer, Long, LongAccumulator, LongAdder, Short。

Integer 继承结构

源码中可学习的地方

最大值、最小值

/**
 * A constant holding the minimum value an <code>int</code> can
 * have, -2<sup>31</sup>.
 */
public static final int   MIN_VALUE = 0x80000000;
/**
 * A constant holding the maximum value an <code>int</code> can
 * have, 2<sup>31</sup>-1.
 */
public static final int   MAX_VALUE = 0x7fffffff;

高效率计算 q * 100

(q << 6) + (q << 5) + (q << 2)

分析:

  • q << n,表示q乘以2^n
  • q >> n,表示q除以2^n

2^6 + 2^5 + 2^2 = 64 + 32 + 4 = 100

高效率判断 一个数是否是2的幂

if( (n & -n) == n)

测试用例:

@Test
public void testInteger() {
    System.out.println(Integer.toBinaryString(4));
    System.out.println(Integer.toBinaryString(-4));
    System.out.println(4 & (-4));
}

结果

100
11111111111111111111111111111100
4

其实还可以用如下判断,因为2的幂,只有一位是1,其余位全是0;如果-1的话,就变成原来位为1位置的后置位全为1。例如8为1000,8-1=7为0111

if( n & (n - 1) == 0)

Integer 的缓存(坑)

先看下面的示例:

@Test
public void testInteger() {
    Integer i1 = 127, i2 = 127;
    System.out.println("127 i1 == i2: " + (i1 == i2));
    i1 = 128; i2 = 128;
    System.out.println("128 i1 == i2: " + (i1 == i2));
    System.out.println("128 equals: " + i1.equals(i2));
}

输出的结果是:

127 i1 == i2: true
128 i1 == i2: false
128 equals: true

为什么对于Integer是127的对象,用==竟然是相同的对象呢?

这是因为Integer类内部,对值为-128127的对象,进行了缓存!这些对象是在JVM加载Integer时就创建好的。

对应的源码为:

public static Integer valueOf(int i) {
    if(i >= -128 && i <= IntegerCache.high)
        return IntegerCache.cache[i + 128];
    else
        return new Integer(i);
}

我们可以看到,如果i在-128和IntegerCache.high之间,会返回IntegerCache.cache[i + 128]。类IntegerCache已经缓存了值为-128和IntegerCache.high的Integer对象。

注释中解释了为什么要这么设计(为了节省时间和空间,-128~127可能是最常用的):

 If a new Integer instance is not required, this method should generally be used in preference to the constructor Integer(int), as this method is likely to yield significantly better space and time performance by caching frequently requested values.
private static class IntegerCache {
    static final int high;
    static final Integer cache[];
    static {
        final int low = -128;
        // high value may be configured by property
        int h = 127;
        if (integerCacheHighPropValue != null) {
            // Use Long.decode here to avoid invoking methods that
            // require Integer's autoboxing cache to be initialized
            int i = Long.decode(integerCacheHighPropValue).intValue();
            i = Math.max(i, 127);
            // Maximum array size is Integer.MAX_VALUE
            h = Math.min(i, Integer.MAX_VALUE - -low);
        }
        high = h;
        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);
    }
    private IntegerCache() {}
}

h 默认是 127,但是可以通过 vm 参数指定:-XX:AutoBoxCacheMax。

/**
 * Cache to support the object identity semantics of autoboxing for values between 
 * -128 and 127 (inclusive) as required by JLS.
 *
 * The cache is initialized on first usage. During VM initialization the
 * getAndRemoveCacheProperties method may be used to get and remove any system
 * properites that configure the cache size. At this time, the size of the
 * cache may be controlled by the vm option -XX:AutoBoxCacheMax=<size>.
 */
// value of java.lang.Integer.IntegerCache.high property (obtained during VM init)
private static String integerCacheHighPropValue;
static void getAndRemoveCacheProperties() {
    if (!sun.misc.VM.isBooted()) {
        Properties props = System.getProperties();
        integerCacheHighPropValue =
            (String)props.remove("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null)
            System.setProperties(props);  // remove from system props
    }
}

相关文章

  • 享元模式源码分析

    JDK源码分析 Integer Integer的缓存默认范围是:-128~127 Integer可设置最大值:12...

  • JDK源码分析 Integer

    说明 对于JDK源码分析的文章,仅仅记录我认为重要的地方。源码的细节实在太多,不可能面面俱到地写清每个逻辑。所以我...

  • 2018-04-24常用类

    常用类_包装类_Integer_Number_JDK源码分析 把一个数zuoweiobject处理

  • JDK源码 -- Integer

    一、概念 类定义: 继承Number抽象类,表明是个数字类型。 实现Comparable接口,可进行比较。 特点:...

  • java.lang.Integer#parseInt() 源码分

    java.lang.Integer#parseInt() 源码分析 Integer#parseInt() 是我们经...

  • Integer源码分析——下(jdk11)

    Integer与原生类型转换 Integer提供了几个与原生类型转换的方法: 由上面的源码可知,Integer类型...

  • JDK 源码解析 —— Integer

    说到Java中的Integer包装类,大家或多或少的都听说过Integer缓存,下面我们先从Integer缓存相关...

  • JDK源码解析-Integer

    一个有东西的需求: 要求在swap()方法里处理后输入a=2,b=1 错误示例1 示例1原因解析 输出结果:a =...

  • java.lang.Integer源码分析

    Integer 本文源码基于JDK8 Integer也是我们经常使用的工具类、包装类,此文主要用于记录学习笔记,主...

  • Integer源码分析

    title: Integer源码分析date: 2017-09-11 15:07:46tags: javacate...

网友评论

    本文标题:JDK源码分析 Integer

    本文链接:https://www.haomeiwen.com/subject/ufjnlxtx.html