java中interger享元模式_Integer类型与享元模式

工程中某方法返回一个Integer:virusRes

另有:某枚举类:

4668558.html

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public enumVirusCheckRes {2

3 UNKNOW(0), SAFE(1), HIGH_RISK(2), MEDIUM_RISK(3), LOW_RISK(4);4

5 privateInteger status;6 privateVirusCheckRes(Integer status){7 this.status =status;8 }9 publicInteger getStatus() {10 return this.status;11 }12 public voidsetStatus(Integer status) {13 this.status =status;14 }15

16 }

View Code

在做如下判断时:

if (VirusCheckRes.SAFE.getStatus() == virusRes)

4668558.html

当virusRes和SAFE都=1 时,结果返回的false

老生常谈的问题,即便是Integer这样的基础变量包装类,判断等于(==)的时候,也是比较对象的地址,而非对象的值,如果比较对象的值,请出门左拐用equals。

but!(Integer类源码)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public booleanequals(Object obj) {if (obj instanceofInteger) {return value ==((Integer)obj).intValue();

}return false;

}

View Code

4668558.html

即便是equals,也是比较的intValue(),所以为了代码看起来更易读,还是直接使用VirusCheckRes.SAFE.getStatus().intValue() == virusRes.intValue(),比较好。

既然聊到了Integer,就在多扯两句,Integer与享元模式:

采用http://blog.csdn.net/gaoxueyi551/article/details/9091349中的例子:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classTest {/***@paramargs*/

public static voidmain(String[] args) {//TODO Auto-generated method stub

Integer a1= new Integer(4);

Integer a2= new Integer(4);

System.out.println(a1== a2); //false

Integer i1= 13;

Integer i2= 13;

System.out.println(i1== i2); //true

Integer i3= 128;

Integer i4= 128;

System.out.println(i3== i4); //false

Integer i5= Integer.valueOf(3);

Integer i6= Integer.valueOf(3);

System.out.println(i5== i6); //true

Integer i7= Integer.valueOf(128);

Integer i8= Integer.valueOf(128);

System.out.println(i7== i8); //false

}

}

View Code

a1==a2  -> false可以理解,跟我的错误一样

i1==i2    -> true 就有点意思了

接下来

i3 = i4     -> false(与i1=i2有什么区别?)

i5 == i6   -> true 什么鬼

i7==i8     -> false

根据a1 != a2 ,i1 == i2, i5 == i6,可以看出,自动装箱用的应该是valueOf方法,而非构造方法,从反编译得到的字节码中也可以证明这点

4668558.html

源码为:

public classMain {public static voidmain(String[] args) {

Integer i= 10;int n =i;

}

}

反编译的字节码

6a873901b77401284feb708d38330622.png

同样可以看出,拆箱时,用的是intValue方法

那么为什么3还好好的,128经过装箱之后就返回的false呢?

看了Integer的源码真的感觉jdk的强大啊,这里用到了设计模式中的享元模式:

上文书说道装箱用到了i1==i2和i5 == i6都返回了true,而且又说道这四个变量其实都用到了相同的方法valueOf,那么就来看看valueOf

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

return newInteger(i);

}

4668558.html

IntegerCache.cache[] 是什么鬼?

818

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

private static classIntegerCache {static final inthigh;static finalInteger 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++);

}privateIntegerCache() {}

}

View Code

4668558.html

(integerCacheHighPropValue貌似可以通过JVM配置)

4668558.html

//value of java.lang.Integer.IntegerCache.high property (obtained during VM init)

private static String integerCacheHighPropValue;

从代码中可以看出,IntegerCache是Integer中的内部类,里面定义了两个属性,high,cache,其中high在static块中给出了赋值,如果配置integerCacheHighPropValue的话,默认的high是127,low=-128

现在再回过头看

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

return newInteger(i);

}

4668558.html

如果i属于[-128,127],则返回cache[i+128],cache如代码所示,是IntegerCache的一个静态数组,是保存一份哦

因此,当自动装箱的i在[-128,127]范围内,则不生成新的Integer,而是共享了一个Integer对象。(享元模式)

超出该范围的Integer才真正的new出了Integer对象。

其他的如Long,Double,Float,Boolean等类型,不再啰嗦。

以上。

参考资料:

http://blog.csdn.net/gaoxueyi551/article/details/9091349

http://www.cnblogs.com/dolphin0520/p/3780005.html

http://1006836709.iteye.com/blog/1714378

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值