您的位置:首页 > 其它

Long与Integer的总结

2016-04-09 12:26 393 查看
前言:

一直以为包装类和String有相似的地方,直到遇到了一些代码的输出结果和自己所想不同,才发现需要去仔细的研究一下包装类的性质。主要的内容是参考收集的资料。

问题

Long与Ineger都是包装类型,是对象。而不是普通类型long与int , 所以它们在比较时必须都应该用equals,或者先使用longValue()或intValue()方法来得到他们的基本类型的值然后使用==比较也是可以的。但是有一种特殊情况, 其实Long与Integer都将 -128~127 这些对象缓存了。 可以看看Long类型源码里面有一个LongCache类,代码如下:

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);
}
}


例子代码

public class Test05 {
public static void main(String[] args) {
Long a = 5L;
Long b = 5L;
System.out.println("a == b ? " + (a == b));

Long c = 129L;
Long d = 129L;
System.out.println("c == d ? " + (c == d));
}
}


打印结果:

a == b ? true

c == d ? false

原因

首先来看看 Long a = 5L ; 它是如何将一个基本类型long包装成一个对象Long的 。可以写一个测试类,然后反编译一下,看看java它是如何解析Long a = 5L这样一条命令的。

测试类如下:

public class Test06 {

Long l = 3L;

}

然后使用javap -verbose Test06 就能看到反编译的结果了, 下面是输出的部分:

{
java.lang.Long l;

public com.spring.test.Test06();
Code:
Stack=3, Locals=1, Args_size=1
0:   aload_0
1:   invokespecial   #10; //Method java/lang/Object."<init>":()V
4:   aload_0
5:   ldc2_w  #12; //long 3l
8:   invokestatic    #14; //Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
11:  putfield        #20; //Field l:Ljava/lang/Long;
14:  return
LineNumberTable:
line 3: 0
line 5: 4
line 3: 14

LocalVariableTable:
Start  Length  Slot  Name   Signature
0      15      0    this       Lcom/spring/test/Test06;
}


从Code中的8可以看出调用了Long的一个类方法Long.valueOf(Long) , 所以可以得到的结论是Long a = 5L实际上等于 Long a = Long.valueOf(5) ;

然后再看看Long.valueOf()方法是如何定义的:

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);
}


一目了然,会先判断基本类型的值如果在-128~127之间,就会直接从LongCache里面取出缓存的对象返回,否则就new一个新的Long对象返回 。

现在就不难理解Test05程序执行得到的结果了,因为a与b等于5,在-127~128之内,所以都是直接从LongCache里面返回的一个Long对象,所以他们在使用==比较的时候,就是相等的(对于对象类型来说,==比较的是两个对象的引用指向堆中的地址) ,而c与d等于129,不在-127~128之间,所以他们他们是分别new出来的两个新的Long对象,使用==来比较自然是不相等的了。

Long重写了equals方法

public boolean equals(Object obj) {
if (obj instanceof Long) {
return value == ((Long)obj).longValue();
}
return false;
}


参考博客:/article/7842646.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: