`

奇怪的Java题:为什么1000 == 1000返回为False,而100 == 100会返回为True?

阅读更多

这是我们今天要讨论的话题,因为我觉得它非常的有趣。

如果你运行如下代码:

1
2
3
4
Integer a = 1000, b = 1000
System.out.println(a == b);//1
Integer c = 100, d = 100
System.out.println(c == d);//2

你会得到以下运行结果:

1
2
false
true

我们知道,如果两个引用指向同一个对象,那么==就成立;反之,如果两个引用指向的不是同一个对象,那么==就不成立,即便两个引用的内容是一样的。因此,结果就会出现false。

这是非常有趣的地方。如果你查看Integer.java类,你会找到IntegerCache.java这个内部私有类,它为-128到127之间的所有整数对象提供缓存。

这个东西为那些数值比较小的整数提供内部缓存,当进行如此声明时:

1
Integer c = 100;

它的内部就是这样的:

1
Integer i = Integer.valueOf(100);

如果我们观察valueOf()类函数,我们可以看到

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

如果值在-128到127之间,它就会返回该缓存的实例。

因此。。。

1
Integer c = 100, d = 100;

两者指向同样的对象。

这就是为什么这段代码的结果为true了:

1
System.out.println(c == d);

现在你可能会问,为什么会为-128到127之间的所有整数设置缓存?

这是因为在这个范围内的小数值整数在日常生活中的使用频率要比其它的大得多,多次使用相同的底层对象这一特性可以通过该设置进行有效的内存优化。你可以使用reflection API任意使用这个功能。

运行下面的这段代码,你就会明白它的神奇所在了。

1
2
3
4
5
6
7
8
9
10
11
12
13
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
  
      Class cache = Integer.class.getDeclaredClasses()[0]; //1
      Field myCache = cache.getDeclaredField("cache"); //2
      myCache.setAccessible(true);//3
  
      Integer[] newCache = (Integer[]) myCache.get(cache); //4
      newCache[132] = newCache[133]; //5
  
      int a = 2;
      int b = a + a;
      System.out.printf("%d + %d = %d", a, a, b); //
    }

 

本文翻译自dzone.com,由回忆和感动翻译,本文第一地址

2
1
分享到:
评论
3 楼 account.redsun.xp 2016-02-23  
博主,这个是有java相关规范要求的还是只是特定的实现,换一个实现就可能有不同的结果?
2 楼 yybing110 2016-02-22  
   
1 楼 小鱼不爱水 2016-02-22  
[size=x-large]127以下是int值,以上要new Integer(1000);[/size]

相关推荐

    this is a res

    android:layout_width="100dp" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_below="@+id/fill_text" android:layout_marginStart="80dp" android:...

    JS中的==运算: [”] == false —true

    根据图1,需要将布尔类型转为数字类型,而false转为数字的结果是0,所以表达式变为: [”] == 0 两个操作数变成了对象类型、数字类型。根据图1,需要将对象类型转为原始类型: 首先调用[].valueOf(),由于数组的...

    VMware 硬盘 共享

    disk.locking = "false" diskLib.dataCacheMaxSize = "0" scsi1.present = "TRUE" scsi1.virtualDev = "lsilogic" scsi1:5.present = "TRUE" scsi1:5.fileName = "E:\redhat\share_disk\Quorum.vmdk" scsi1:6....

    Java 最常见的 208 道面试题:第一模块答案

    Java 最常见的 208 道面试题:第一模块答案 JDK 和 JRE 有什么区别? == 和 equals 的区别是什么? 两个对象的 hashCode()相同,则 equals()也一定为 true,对 吗? final 在 java 中有什么作用? java 中的 Math....

    Android android:exported = true 用法详解

    Android相关属性的介绍:android:exported = true 在Activity中该属性用来标示:当前Activity是否可以被另一个Application的组件启动:true允许被启动;false不允许被启动。 android:exported 是Android中的四大...

    可配置阴影颜色和投影方向的CardView

    根据Android原生CardView源码进行修改封装,新增加十个属性,分别控制四个边和四...默认四边四角投影为显示,配置为false不显示 为true显示。cardShadowStartColor:阴影起始颜色。 cardShadowEndColor:阴影结束颜色。

    位字段:n布尔值= 1整数,保存列和迁移

    例如,true-false-false = 1,false-true-false = 2,true-false-true = 5(1,2,4,8,..) class User < ActiveRecord xss=removed> :seller , 2 => :insane , 4 => :sensibleenduser = User . new ( seller : true...

    SAP HANA JDCB

    reconnect=true&currentschema=yuto #jdbc.driver=com.sap.db.jdbc.Driver #jdbc.url=jdbc:sap://port:30015?reconnect=true&currentschema=CUSTOMIZE #jdbc.username=**** #jdbc.password=***** #hibernate.dialect...

    android源码-漂亮的qq界面

    android:background="@drawable/option" android:clickable="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="13.0dip" android:layout_...

    Python算法题源代码-LeetCode(力扣)-搜索二维矩阵

    力扣热题Python源代码 题目74. 搜索二维矩阵 给你一个满足下述两条属性的 m x n 整数矩阵: 每行中的整数从左到右按非严格递增顺序排列。 每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target ,如果 ...

    自定义SeekBar样式

    如何自定义seekBar的样式 ... <item android:state_focused="false" android:state_pressed="false" android:drawable="@drawable/bg" /> 3:同样可以定义进度条样式,在seekbar_img.xml中自定义样式。

    appconfignet

    useDefaultWebProxy="true"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <security mode="None">

    自定义CheckBox样式

    如何自定义CheckBox的样式 1:首先在布局文件中添加... <item android:drawable="@drawable/checkBtn_off" android:state_checked="false" android:state_enabled="true"> 以上三步之后,实现CheckBox的样式自定义

    PZ.rar_True and False

    bModified:=false bError:=false bCloseWarning:=false bNewPZ:=true setwindowlong(handle,gwl_style,getwindowlong(handle,gwl_style) and not ws_maximizebox) left:=(screen.Width -width) div 2 top:=...

    网络媒体播放器源代码

    // true = 自动播放 (一般站长会选择这个方式) // false = 不要自动播放,等待使用者启动播放器 var blnAutoStart = true; // ?随机播放? // 设定曲目的预设播放顺序,是否随机(随机数/Random Playing)播放...

    Elasticsearch的交互库Elastomer-Client.zip

    Elastomer-Client 为 ElasticSearch API endpoint 提供一个一对一的映射。API 通过你想要实现的来分解为逻辑部分和访问,每一个逻辑部分代表一个客户端类。示例代码:require 'elastomer/client' client = ...

    Python期末试题题库完整.docx

    若 a=True,b=False若 a=True,b=False则 a or b 为 True则 a or b 为 TrueB.B.若 a=True,b=False若 a=True,b=False则 a and b 为 False则 a and b 为 FalseC.C.若 a=True,b=False若 a=True,b=False则 not a 为 False...

    Android 上应用Googlemap

    protected boolean isRouteDisplayed() { return false; } } //----------------- <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:...

    snappool数据库连接池的应用

    useUnicode=true&characterEncoding=gbk dbUser =root dbPass =113200 connectionPoolSize= 25 statementPoolSize= 50 idleTimeout= 30 shrinkInterval= 80 } SQLServer { driverClass = com.inet.tds.TdsDriver ...

    uniapp 使用map组件 动态自定义图标及文字

    <free-scroll-main :scrollView='false' :showTabber="false" scrollViewStyle="background-color: #fafaf9;"> </free-scroll-main> --> <view class="bg-dark" style="height: 870rpx; width: 750rpx;"> ...

Global site tag (gtag.js) - Google Analytics