Java中Integer与int类型的比较--装箱和拆箱
2015-08-24 11:01
507 查看
先上例子:下面的代码输出什么?
结果:
其实Integer与int类型的赋值与比较最关键的一点就是:这两个变量的类型不同。Integer是引用类型,int是原生数据类型。
我们分四种情况来讨论:
1) Integer与int类型的赋值
a.把Integer类型赋值给int类型。此时,int类型变量的值会自动装箱成Integer类型,然后赋给Integer类型的引用,这里底层就是通过调用valueOf()这个方法来实现所谓的装箱的。
b.把int类型赋值给Integer类型。此时,Integer类型变量的值会自动拆箱成int类型,然后赋给int类型的变量,这里底层则是通过调用intValue()方法来实现所谓的拆箱的。
2) Integer与int类型的比较
这里就无所谓是谁与谁比较了,Integer == int与int == Integer的效果是一样的,都会把Integer类型变量拆箱成int类型,然后进行比较,相等则返回true,否则返回false。同样,拆箱调用的还是intValue()方法。
3) Integer之间的比较
这个就相对简单了,直接把两个引用的值(即是存储目标数据的那个地址)进行比较就行了,不用再拆箱、装箱什么的。
4) int之间的比较
这个也一样,直接把两个变量的值进行比较。
值得注意的是:对Integer对象,JVM会自动缓存-128~127范围内的值,所以所有在这个范围内的值相等的Integer对象都会共用一块内存,而不会开辟多个;超出这个范围内的值对应的Integer对象有多少个就开辟多少个内存。
至于题目中,a+c==d是true,a+c==e也是true,但是d==e是false,我是这么理解的:a+c在运算的时候可能都是拆箱为int计算,然后得到的int值再与Integer的d进行比较,这个时候就如上面所说,会把Integer拆箱为int进行比较。d==e为false其实是好理解的,Integer是引用类型,== 比较的是两个变量的引用,通过new之后的引用与前面的肯定就不一样了。
对于a+c==f为true,a+c也是先拆箱计算,再与Long型的f比较,f也应该要拆箱,然后int与long进行比较。
对于f.equals(a+c)为false,要看Long的equals方法是怎么实现的了,下面是Long的equals方法的源码,可以看到它会先判断是否是同一类型,不是则返回false,所以f.equals(a+c)为false。
</pre><pre name="code" class="java"><span style="white-space:pre"> </span> Integer a = 1; Integer b = 1; Integer c = 2; Integer d = 3; Integer e = new Integer(3); Integer e1 = new Integer(3); Long f = 3L; Long f1 = new Long(3); int a1 = 1; int b1 = 1; int c1 = 2; int d1 = 3; System.out.println("1== Integer(1) ?:" + (new Integer(1) == 1)); System.out.println("a==a1 ?:" + (a==a1)); System.out.println("a==b ?:" + (a==b)); System.out.println("d==e ?:" + (d==e)); System.out.println("e1==e ?:" + (e1==e)); System.out.println("a + c == d ?:" + (a + c == d)); System.out.println("a + c == e ?:" + (a + c == e)); System.out.println("a + c == f ?:" + (a + c == f)); System.out.println("a1 + c1== f ?:" + (a1 + c1 == f)); System.out.println("a1 + c1== f1 ?:" + (a1 + c1 == f1)); System.out.println("a + c equals f ?:" + f.equals(a+c));
结果:
其实Integer与int类型的赋值与比较最关键的一点就是:这两个变量的类型不同。Integer是引用类型,int是原生数据类型。
我们分四种情况来讨论:
1) Integer与int类型的赋值
a.把Integer类型赋值给int类型。此时,int类型变量的值会自动装箱成Integer类型,然后赋给Integer类型的引用,这里底层就是通过调用valueOf()这个方法来实现所谓的装箱的。
b.把int类型赋值给Integer类型。此时,Integer类型变量的值会自动拆箱成int类型,然后赋给int类型的变量,这里底层则是通过调用intValue()方法来实现所谓的拆箱的。
2) Integer与int类型的比较
这里就无所谓是谁与谁比较了,Integer == int与int == Integer的效果是一样的,都会把Integer类型变量拆箱成int类型,然后进行比较,相等则返回true,否则返回false。同样,拆箱调用的还是intValue()方法。
3) Integer之间的比较
这个就相对简单了,直接把两个引用的值(即是存储目标数据的那个地址)进行比较就行了,不用再拆箱、装箱什么的。
4) int之间的比较
这个也一样,直接把两个变量的值进行比较。
值得注意的是:对Integer对象,JVM会自动缓存-128~127范围内的值,所以所有在这个范围内的值相等的Integer对象都会共用一块内存,而不会开辟多个;超出这个范围内的值对应的Integer对象有多少个就开辟多少个内存。
至于题目中,a+c==d是true,a+c==e也是true,但是d==e是false,我是这么理解的:a+c在运算的时候可能都是拆箱为int计算,然后得到的int值再与Integer的d进行比较,这个时候就如上面所说,会把Integer拆箱为int进行比较。d==e为false其实是好理解的,Integer是引用类型,== 比较的是两个变量的引用,通过new之后的引用与前面的肯定就不一样了。
对于a+c==f为true,a+c也是先拆箱计算,再与Long型的f比较,f也应该要拆箱,然后int与long进行比较。
对于f.equals(a+c)为false,要看Long的equals方法是怎么实现的了,下面是Long的equals方法的源码,可以看到它会先判断是否是同一类型,不是则返回false,所以f.equals(a+c)为false。
相关文章推荐
- Spring 和EJB终于统一融合(转)
- ThreadPoolExecutor基本原理
- 内存不足 java.lang.OutOfMemoryError: Java heap space
- java spring 邮件发送
- JAVA基础7(代码剖析)
- eclipse4.4反编译安装
- JAP和Spring整合的三种方式
- Struts2与Servlet的关系
- Java中莫名其妙的时区错误
- 访问单个节点的删除(Java)
- 深入理解Java:注解(Annotation)基本概念
- Java知识总结--快速搭建Java开发环境(一)
- struts2拦截了servlet请求的解决
- Java关键字之static
- Java关键字之static
- Java关键字之static
- Struts2中出现 Dispatcher initialization failed错误
- Spring MVC的多视图解析器配置及与Freemarker的集成
- Java中HashMap和TreeMap的区别深入理解
- Myeclipse...Failed to create the java Virtual Machine