美高梅开户-美高梅官方网站开户

您的位置:美高梅开户 > 美高梅开户 > 美高梅开户Java开发之路

美高梅开户Java开发之路

发布时间:2019-08-17 22:34编辑:美高梅开户浏览(130)

    [Java开发之路](19)Long缓存问题

    Long中有个小小的陷阱,就是在-128至127范围内,Long.valueOf(long l)返回的Long的实例是相同的,而在此范围之外每次使用valueOf(long l)时,返回的实例都是不同的。

    举例:

    1. System.out.println(Long.valueOf(-129) == Long.valueOf(-129)); // false
    2. System.out.println(Long.valueOf(-128) == Long.valueOf(-128)); // true
    3. System.out.println(Long.valueOf(127) == Long.valueOf(127)); // true
    4. System.out.println(Long.valueOf(128) == Long.valueOf(128)); // false

    下面我们通过Long源码进行分析一下:

    1. public static Long valueOf(long l) {
    2. final int offset = 128;
    3. if (l >= -128 && l <= 127) { // will cache
    4. return LongCache.cache[(int)l offset];
    5. }
    6. return new Long(l);
    7. }

    从上面代码中我们可以看出先判断传递过来的数值是否在[-128,127]之间,如果是则直接从缓存中返回对应的引用,否则新创建一个Long的实例。所以说如果不在这个区间范围内,返回一个新创建的Long类型引用,用==判断就会理所当然的返回false,地址不一样。但是如果我们使用equals方法,则会返回true,数值是一样的。

    1. Long.valueOf(128).equals(Long.valueOf(128)) // true

    我们看看对于在区间范围之内,是如何返回对应的引用?最重要的是Long类中有一个静态的内部类LongCache,专门用于缓存-128至127之间的值。

     

    1. private static class LongCache {
    2. private LongCache(){}
    3. 美高梅开户 , 
    4. static final Long cache[] = new Long[-(-128) 127 1];
    5.  
    6. static {
    7. for(int i = 0; i < cache.length; i )
    8. cache[i] = new Long(i - 128);
    9. }
    10. }

    在LongCache类中定义了一个cache数组,来存储缓存数据。我们可以看到cache数组的长度:-(-128)

    • 127 1,很明了的知道缓存数据从-128到127,后面的1代表数字0,一共256个元素。

    valueOf这个方法设计比较好的一点是offset,它的初始值设为128,目的就是为了数组下标128处存放0,这样就将正数和负数分隔开。

    Long中有个小小的陷阱,就是在-128至127范围内,Long.valueOf(long l)返回的Long的实例是相同的,而在此范围之外...

    首先我们对两个Integer进行比较

            Integer integer1 = 3;
            Integer integer2 = 3;
            if (integer1 == integer2)
                System.out.println("integer1 == integer2");
            else
                System.out.println("integer1 != integer2");
            Integer integer3 = 300;
            Integer integer4 = 300;
            if (integer3 == integer4)
                System.out.println("integer3 == integer4");
            else
                System.out.println("integer3 != integer4");
    

    上面的程序允许结果如下:

    integer1 == integer2
    integer3 != integer4
    

    Java 编译器把原始类型自动转换为封装类的过程称为自动装箱(autoboxing),这相当于调用 valueOf 方法

    Integer integer1 = 3;
    Integer integer2 = Integer.valueOf(3);
    

    其中valueOf源码如下:

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

    本文由美高梅开户发布于美高梅开户,转载请注明出处:美高梅开户Java开发之路

    关键词: 美高梅开户

上一篇:ClassLoader究竟为何物

下一篇:没有了