前言

Java中有两种类型

  • 基本类型

基本数据类类型存的是数值本身

  • 引用类型

引用类型变量在内存放的是数据的引用

基本类型通过==比较的是他们的值大小,而引用类型比较的是他们的引用地址

正文

在一些特殊的类中,如Integer在使用==比较的时候往往非常容易出错,下面通过几个例子来探索一下具体的原理

代码片段

public class Test03 {

    public static void main(String[] args) {
Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150; System. out.println( f1 == f2); //true
System. out.println( f3 == f4); //false
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

当我们给一个Integer赋予一个int类型的时候会调用Integer的静态方法valueOf。 

Integer f1 = Integer.valueOf(100); 

Integer f2 = Integer.valueOf(100); 

Integer f3 = Integer.valueOf(150); 

Integer f4 = Integer.valueOf(150); 

思考:那么Integer.valueOf()返回的Integer是不是是重新new Integer(num);来创建的呢?如果是这样的话,那么== 比较返回都是false,因为他们引用的堆地址不一样。

具体来看看Integer.valueOf的源码

public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

在IntegerCache中cache数组初始化如下,存入了-128 - 127的值

cache = new Integer[(high - low) + 1];
int j = low;
for( int k = 0; k < cache.length ; k ++)
cache[k] = new Integer(j ++);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

从上面我们可以知道给Interger 赋予的int数值在-128 - 127的时候,直接从cache中获取,这些cache引用对Integer对象地址是不变的,但是不在这个范围内的数字,则new Integer(i) 这个地址是新的地址,不可能一样的

代码片段

public static void main(String[] args) {
Integer a = new Integer(3);
Integer b = 3;
int c = 3;
System.out.println(a == b);
System.out.println(a == c);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

a == b分析 

Integer b = 3; 自动调用Integer.valueOf(3) 返回一个Integer的对象。 这个对象存放到cache中的(上面一段代码分析)。 而 Integer a = new Integer(3);这里创建了一个新的对象Integer 所以 a == b 返回的是false

a == c 分析 

一个Integer 与 int比较,先将Integer转换成int类型,再做值比较,所以返回的是true。

参考资料:《探索java基本类型和包装类型的使用运算符==进行比较的底层细节》

延伸

java中还有与Integer类似的是Long,它也有一个缓存,在区间[-128,127]范围内获取缓存的值,而Long与long比较的时候先转换成long类型再做值的比较

Double类型,它没有缓存,但是当Double与double比较的时候会先转换成double类型,再做值的比较

源地址:http://blog.csdn.net/sgls652709/article/details/49079767

Integer类型与int的==比较的更多相关文章

  1. 转:JAVA里面的int类型 和Integer类型,有什么不一样

    JAVA里面的int类型 和Integer类型,有什么不一样 原文链接:http://blog.csdn.net/wuxinliulei/article/details/11099565 java.l ...

  2. JAVA里面的int类型 和Integer类型,有什么不一样

    JAVA里面的int类型 和Integer类型,有什么不一样 原创 2013年09月04日 23:15:11 标签: java / 2120 编辑 删除 JAVA里面的int类型 和Integer类型 ...

  3. 如果不空null并且不是空字符串才去修改这个值,但这样写只能针对字符串(String)类型,如果是Integer类型的话就会有问题了。 int i = 0; i!=''。 mybatis中会返回tr

    mybatis 参数为Integer型数据并赋值0时,有这样一个问题: mybatis.xml中有if判断条件判断参数不为空时,赋值为0的Integer参数被mybatis判断为空,因此不执行< ...

  4. java-int类型:int默认为0导致更新操作未赋值的情况下将值更新为0

    日常开发中,做更新操作的时候的处理方法为:当这个字段有值则更新,没有值就不更新,在mybatis的xml中表现为: <!-- 修改记录,只修改只不为空的字段 --> <update ...

  5. java中两个Integer类型的值相比较的问题

    今天在做一个算法时,由于为了和其他人保持接口的数据类型一致,就把之前的int换为Integer,前几天测了几组数据,和之前的结果一样,但是今天在测其它数据 的时候,突然出现了一个奇怪的bug,由于之前 ...

  6. Integer ,==,int 的使用

    面试比较常见的题目:自己也经常忘记,所以就记下来了 上代码: Integer a = ,b=; Integer c = ,d=; System.out.println(a==b); System.ou ...

  7. Java进阶(二十三)java中long类型转换为int类型

    java中long类型转换为int类型 由int类型转换为long类型是向上转换,可以直接进行隐式转换,但由long类型转换为int类型是向下转换,可能会出现数据溢出情况: 主要以下几种转换方法,供参 ...

  8. java中将string类型转int类型或者将string类型转long类型方法

    将字串 String 转换成整数 int 两种方法: 1).int i = Integer.parseInt("111"); 或 i = Integer.parseInt([Str ...

  9. 我今天遇到的条件语句Integer类型的

    两个Integer类型的值进行比较时,应该用equals进行判断,用"=="判断是错误的,后来想了一下就明白了,Integer毕竟是对象, 而不是int基本数据类型,可以直接比较, ...

随机推荐

  1. Java 中初始化 List 集合的 7 种方式

    1.常规方式 List<String> languages = new ArrayList<>(); languages.add("Java"); lang ...

  2. JDBC处理mysql大数据

    大数据也称之为LOB(Large Objects),LOB又分为:clob和blob,clob用于存储大文本,blob用于存储二进制数据,例如图像.声音.二进制文等. 在实际开发中,有时是需要用程序把 ...

  3. Spring Cloud官方文档中文版-Spring Cloud Config(上)-服务端(配置中心)

    官方文档地址为:http://cloud.spring.io/spring-cloud-static/Dalston.SR2/#spring-cloud-feign 文中例子我做了一些测试在:http ...

  4. hadoop2.7.3启动报错问题

    在日志里面可以看出是没有对应的权限,因此在hdfs_site.xml中添加 <property> <name>dfs.permissions</name> < ...

  5. Webdriver元素定位的方法

    webdriver提供了8种元素定位方法: 1.id 2.name 3.tag name 4.class name 5.link text 6.partial link text 7.xpath 8. ...

  6. 在C#一个程序中,将一个窗体中的数据传送到另一个窗体

    使用多个窗体搭建的程序,需要用到窗体间的数据传递,常用两种方法: 方法一 1,进入子窗体的Designer.cs,将子窗体中的私有控件控件定义为public 2.在主窗口程序Form1.cs中将子窗口 ...

  7. PLC与上位机的socket通讯——上位机C#程序(二)

    C#的网口通信 一.命令行 客户端程序:using System;using System.Collections.Generic;using System.Linq;using System.Tex ...

  8. sql注入(从入门到进阶)

    随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多.但是由于这个行业的入门门槛不高,程序员的水平及经验也参差不齐,相当大一部分程序员在编写代码的时候,没有对用户输入数据的合法性进 ...

  9. '\b'退格符号笔记

    今天在给小孩儿讲for循环输出最后一个输出项没有空格的情况 借助标记,选择在第二个至最后一个的输出项前添加空格 ; ; i < n; i++) { ) cout << a[i]; e ...

  10. 上手Dubbo之 环境搭建

    和传统ssm整合--写XML配置文件 搭建服务的提供者和服务的消费者,实现服务消费者跨应用远程调用服务提供者 公共模块抽取 公共模块的抽取 服务的消费者远程调用服务的提供者, 最起码他自己要得到在服务 ...