文档章节

java当中Integer==、equals以及cache

getqiu
 getqiu
发布于 2016/08/11 11:07
字数 713
阅读 8
收藏 0

经常遇到 用 `==`比较两个基本类型自动装箱后的对象,有些时候总让人晕,今天总体梳理一下这个问题。

梳理这个问题之前,先来看看最近遇到的一些程序片段:

public void integerCache()
{
    Integer number1 = new Integer(10);
    Integer number2 = new Integer(10);
    System.out.println("number1 == number2:"+(number1 == number2)); //@1

    Integer number3 = 300;
    Integer number4 = 300;
    System.out.println("number3 == number4 :"+(number3 == number4));//@2

    System.out.println("300 == 300 :"+(300 == 300));                //@3

    Integer number5 = Integer.valueOf("67");
    Integer number6 = Integer.valueOf("67");
    System.out.println("number5 == number6:"+(number5 == number6)); //@4

    Integer number7 = Integer.valueOf("128");
    Integer number8 = Integer.valueOf("128");
    System.out.println("number7 == number8:"+(number7 == number8)); //@5
}

遇到的问题大概就是这5类吧,程序输出的结果是这样的:

number1 == number2:false
number3 == number4 :true
300 == 300 :true
number5 == number6:true
number7 == number8:false

一个一个的来分析:

  1. @1 在java当中 `==`对于基本类型来说是判断两个变量的值是否相等(即使类型不同也行,比如21 == 21F),但是对于引用类型,必须是引用地址相等才能算相等,因此@1当中,这个两个引用类型的变量,在堆区的不同位置,因此答案是 false
  2. @2地方比较迷惑人。程序是申明了一个Integer对象,因此在赋值 number3=300时,300会自动装箱,成为Interger(300),又是堆区当中两个不同的对象,所以返回的结果是false。但是:如果把程序中的300改为30,那么结果返回是true?为什么呢?因为在java在初始化Integer时,会自动的缓存(-128,127)的Integer对象,所以当把30自动装箱,那么就会自动引用缓存当中的对象。但是为什么@1当中没有自动引用缓存呢?上面黄色标记的地方说了,在自动装箱的时候才去缓存当中取,没说创建的时候会到缓存当中取。
  3. @3地方,两个基本类型,所以只要值相等,自然就相等了。结果为true。
  4. @4:Integer的valueOf方法也会到缓存当中取对象,而且缓存的范围是(-128,127),故返回值为true,同理@5返回只为false。
  5. @5返回为false。

总之:

遇到这类问题首先要明白的是:

  1. ==判断的依据是什么? `==`对于基本类型来说是判断两个变量的值是否相等(即使类型不同也行,比如21 == 21F),但是对于引用类型,必须是引用地址相等才能算相等。
  2. 当前比较的类型是基本类型还是引用类型?
  3. 如果是引用类型:这两个变量的地址相同吗?(考虑是否被缓存了)

 

大概总结就这样吧,欢迎补充。

© 著作权归作者所有

共有 人打赏支持
getqiu
粉丝 1
博文 12
码字总数 11145
作品 0
朝阳
程序员
你不知道的 equals 和 ==

先来看一道 equals和 == 相关的面试题吧。 先告诉你答案是 true,true,false,true。 i1 == i2 和 i1.equals(i2) 这两个都是 true,大多数人应该可以答对。后面的 i3 == i4 和 i3.equals(i4...

Wizey
昨天
0
0
JVM常量池及字符串==比较分析

Java常量池技术 java中的常量池技术,是为了方便快捷地创建某些对象而出现的,当需要一个对象时,就可以从池中取一个出来(如果池中没有则创建一个),则在需要重复创建相等变量时节省了很多...

陶邦仁
2012/10/21
0
0
Java自动装箱与拆箱及其陷阱

在本文中,笔者向大家介绍下Java中一个非常重要也非常有趣的特性,就是自动装箱与拆箱,并从源码中解读自动装箱与拆箱的原理,同时这种特性也留有一个陷阱。开发者如果不注意,就会很容易跌入...

LCZ777
2014/07/26
0
0
JAVA 中 equals 和 “==”

进行字符串比较时候: == 比较的是两个字符串内存地址的数值是否相等,属于数值比较; equals() 因为 String 重写了 equals 所以比较的是两个字符串的内容,属于内容比较。 总结:java 中 eq...

几个栗子
2017/12/19
0
0
理解Java Integer的缓存策略

本文将介绍 Java 中 Integer 缓存的相关知识。这是 Java 5 中引入的一个有助于节省内存、提高性能的特性。首先看一个使用 Integer 的示例代码,展示了 Integer 的缓存行为。接着我们将学习这...

analogous_love
04/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

这些Spring中的设计模式,你都知道吗?

设计模式作为工作学习中的枕边书,却时常处于勤说不用的尴尬境地,也不是我们时常忘记,只是一直没有记忆。 Spring作为业界的经典框架,无论是在架构设计方面,还是在代码编写方面,都堪称行...

Java填坑之路
24分钟前
1
0
Spring Aop原理之Advisor过滤

在上文(Spring Aop之Advisor解析)中我们讲到,Spring Aop对目标bean的代理主要分为三个步骤:获取所有的Advisor,过滤当前bean可应用的Advisor和使用Advisor为当前bean生成代理对象,并且上文...

爱宝贝丶
35分钟前
0
0
JMockit学习教程

1 JMockit中文网 我觉得如果仅仅是开发自测的话,把JMockit中文网认真看一遍,就可以在项目中使用JMockit了。 http://jmockit.cn/index.htm 2 JMockit中文教程 官方文档中文版。对于不喜欢看...

SuperHeroes
46分钟前
0
0
Linux服务器几乎从不采用Arch Linux?

我们见得多的Linux服务器系统一般都是什么Ubuntu Server啊,什么Cent OS啊,什么Fedora啊,或者企业采用的Red Hat啊,为什么几乎没有Arch Linux呢?下面我将从若干个方面指出Arch Linux在服务...

linux-tao
58分钟前
0
0
js 函数柯里化 闭包

参考 https://mp.weixin.qq.com/s/GEHL3jarDdAAcr5tQGjmDg 一个统计求和的函数 需要知道整个数组的信息,然后遍历求值 function countMoney() { let money = 0 // 温馨提示:arguments...

阿豪boy
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部