Integer中127和128

来源:互联网 发布:mac预览图片 拖动 编辑:程序博客网 时间:2024/06/05 11:53
    int  m=127;    Integer i=m;    Integer i2=m;    System.out.println(i==i2);    m=128;    i=m;    i2=m;    System.out.println(i.equals(i2));    m=127;    i=new Integer(127);    i2=new Integer(127);    System.out.println(i==i2);

这是一道陷阱题,主要讲的是jvm拆箱和装箱,同时涉及到equals和==区别

Java常量池

常量池在java中用于保存编译期已经确定的,它包括了关于类,方法,接口中的常量,也包括字符串常量。例如
String s = “Java” 这种声明的方式。产生的这种”常量”就会被放到常量池,常量池是JVM的一块特殊的内存空间。
使用Java常量池技术,是为了方便快捷地创建某些对象,当你需要一个对象时候,就去这个池子里面找,找不到就在池子里面创建一个。但是必须注意 如果对象是用new 创建的。那么不管是什么对像,它是不会放到池子里的,而是向堆申请新的空间存储。

自动装箱与自动拆箱

那我们来分析Integer i = 5;的过程;
在jdk1.5以前,这样的代码是错误的,必须要通过Integer i = new Integer(5);这样的语句实现;而在jdk1.5以后,Java提供了自动装箱的功能,只需Integer i = 5;这样的语句就能实现基本数据类型传给其包装类,JVM为我们执行了Integer i = Integer.valueOf(5);这就是Java的自动装箱。
相对应的,把基本数据从对应包装类中取出的过程就是拆箱;如
Integer i = 5;
int j = i;//这样的过程就是自动拆箱
源码方面,用一句话总结装箱和拆箱的实现过程:
装箱过程是通过调用包装器的valueOf方法实现的,而拆箱过程是通过调用包装器的 xxxValue方法实现的。(xxx代表对应的基本数据类型)
Integer i = new Integer(xxx)和Integer i =xxx;这两种方式的区别:
1)第一种方式不会触发自动装箱的过程;而第二种方式会触发;
2)在执行效率和资源占用上的区别。第二种方式的执行效率和资源占用在一般性情况下要优于第一种情况(注意这并不是绝对的)。

分析题目

当Integer i=127这种使用会触发自动装箱的过程,于是取常量池去取。
无论Integer i2=127,Integer i3=127声明都指向同一个;
但是到128,由于常量池不会包含128这种数字,即使自动装箱也没有用;

同时new Integer(i)这种形式都不会触发自动装箱,自然==比较也都不一样,
但是equals比较的是值,而不是对象地址

原创粉丝点击