今天在做实验的时候,发现了一个比较奇怪的问题:两个Integer型变量用==进行比较时,有时候能成功有时候不能成功。举个例子:

代码1:

Integer l1 = 122;
Integer l2 = 122;
if(l1 == l2)
System.out.println("Right");
else
System.out.println("Wrong");

  

  运行这段代码时,程序会输出:Right。对于另一个例子:

代码2:

Integer l1 = 233;
Integer l2 = 233;
if(l1 == l2)
System.out.println("Right");
else
System.out.println("Wrong");

  

  运行这段代码时,程序会输出Wrong。但当对代码2进行修改时:

代码3:

Integer l1 = 233;
int l2 = 233;
if(l1 == l2)
System.out.println("Right");
else
System.out.println("Wrong");

  在运行这段代码时,程序会输出Right。如果换一种定义方式时:

代码4:

Integer l1 = 233;
Integer l2 = new Integer(233);
if(l1 == l2)
System.out.println("Right");
else
System.out.println("Wrong");

 运行这段代码时,程序会输出Wrong。

关于这种现象,查了下资料,总结如下:

1.实际上Java中定义的Integer变量会通过Integer.valueOf()方法生成一个实例,即:

Integer l1 = 122 会被编译成 Integer l1 = Integer.valueOf(122),而关于valueOf()方法的源码:

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

看一下源码就会明白,对于-128到127之间的数,会进行缓存,Integer l1 = 122时,会将122进行缓存,下次再写Integer l2 = 122时,就会直接从缓存中取,就不会new了,相当于生成的为同一个对象,。所以代码1的运行结果是Right。

而对于这个范围之外的数值,valueOf()相会重新new一个对象,所以就不相等了,所以代码2的裕兴结果就是Wrong。

2.对于代码3,Integer型变量与int型变量进行比较时,实质上是把Integer类型变量拆箱成int类型,然后进行比较,相等则返回true,否则返回false。此处的拆箱调用的是intValue()方法。所以代码3的运行结果是Right。

3.对于代码4,就比较好解释了,因为new相当于重新定义了一个新的对象,即l1的引用实质是指向在堆中了,而l2实质是指向在常量池中了(关于变量在内存中的位置可参考:http://www.cnblogs.com/wangkundentisy/p/6636340.html),所以两者是不可能相等的,故输出结果就是Wrong。

4.总之,要想比较两个Intger型变量的值最好用Integer.intValue()方法生成int型后再比较。

5.Integer型变量与int型变量之间可以直接比较,此时自动进行拆箱操作。

参考:

  1.https://www.cnblogs.com/liuling/archive/2013/05/05/intAndInteger.html

  2.http://blog.csdn.net/snail_rao/article/details/7639194

  3.《JAVA核心技术》

JAVA中Integer类型变量比较问题的更多相关文章

  1. java中Integer比较需要注意的问题

    java中Integer比较需要注意的问题 package com.srie.test; import java.util.HashMap; import java.util.Map; public ...

  2. java中Integer 和String 之间的转换

    java中Integer 和String 之间的转换 将数组转换成字符串:char[] array = {'a','b','c','d','e'};String str = new String(ar ...

  3. Java中引用类型变量,对象,值类型,值传递,引用传递 区别与定义

    一.Java中什么叫做引用类型变量?引用:就是按内存地址查询       比如:String s = new String();这个其实是在栈内存里分配一块内存空间为s,在堆内存里new了一个Stri ...

  4. java中String类型变量的赋值问题

    第一节 String类型的方法参数 运行下面这段代码,其结果是什么? package com.test; public class Example { String str = new String( ...

  5. Java中Integer的最大值和最小值

    从JDK1.0开始,Integer中就定义了MIN_VALUE和MAX-VALUE两个常量: /** * A constant holding the minimum value an {@code ...

  6. 从源码看java中Integer的缓存问题

    在开始详细的说明问题之前,我们先看一段代码 public static void compare1(){ Integer i1 = 127, i2 = 127, i3 = 128, i4 = 128; ...

  7. Java中Integer的源码学习

      一.开始 public final class Integer extends Number implements Comparable<Integer> 1).由于类修饰符中有关键字 ...

  8. Java中Integer类的方法

    java.lang 类 Integer java.lang.Object java.lang.Number java.lang.Integer 全部已实现的接口: Serializable, Comp ...

  9. Java中Integer和String浅谈

    Java中的基本数据类型有八种:int.char.boolean.byte.long.double.float.short.Java作为一种面向对象的编程语言,数据在Java中也是一种对象.我们用基本 ...

随机推荐

  1. [Data Structure] An Algorithm for Matching Delimiters

    An important task when processing arithmetic expressions is to mach delimiters. We can use Stack to ...

  2. Oracle导入导出表

    使用PL SQL Developer进行操作 一.导出 工具<<导出表<<sql插入<<选择用户和要导出的表,勾选创建表,选择输出文件(格式最好为.sql),点击导 ...

  3. Atcoder 1973:こだわり者いろはちゃん / Iroha's Obsession

    C - こだわり者いろはちゃん / Iroha's Obsession Time limit : 2sec / Memory limit : 256MB Score : 300 points Prob ...

  4. java-方法重写的注意事项

    1.父类中私有方法不能被重写.因为父类的私有方法子类根本就无法继承. 2.子类重写父类方法时,访问权限不能更低.最好就一致. 3.父类静态方法,子类也必须通过静态方法进行重写.其实这个算不上方法重写, ...

  5. ionic1页面间传递参数的问题

    1.  $scope.routeinfo是我要传递的参数--到scheddulcontent这个页面去: $state.go( "scheddulcontent" , { 'rou ...

  6. Vue v-text和v-html的区别

    v-text和v-html的区别 v-text:会把html的标签输出 v-html:不会把html的标签输出 比如: <template> <div id="app&qu ...

  7. 你真的了解word-wrap和word-break的区别吗? (转载)

    这两个东西是什么,我相信至今还有很多人搞不清,只会死记硬背的写一个word-wrap:break-word;word-break:break-all;这样的东西来强制断句,又或者是因为这两个东西实在是 ...

  8. mongodb千万级写入怎么优化

    从mysql数据库通过java程序导入单表1300w到mongodb,花了大概50分钟,前1000w条数据中每100w条大概要3分钟,之后的300多w条就差不多每100w条要5到6分钟,之后再从其他的 ...

  9. spark aggregate函数详解

    aggregate算是spark中比较常用的一个函数,理解起来会比较费劲一些,现在通过几个详细的例子带大家来着重理解一下aggregate的用法. 1.先看看aggregate的函数签名在spark的 ...

  10. sqler sql 转rest api 数据聚合操作

    sqler 2.0 提供了一个新的指令aggregate,注意这个和sql 的聚合函数不是一个概念,这个只是为了 方便api数据的拼接 参考格式   databases {    exec = &qu ...