原文地址:http://angelinafan.blog.163.com/blog/static/1361727982011224112444751/
今天发现一个挺诡异的问题,先来看看下面这段代码:
view
plaincopy
to clipboardprint?publicclassTest{publicstaticvoidmain(String[]args){Integera=1000;Integerb=1000;System.out.println("a==b:"+(a==b));System.out.println("a.equals(b):"+a.equals(b));}}
这段代码的输出结果是这样的:
view
plaincopy
to clipboardprint?a==b:falsea.equals(b):true
对于基本类型,以及基本类型的比较,我一直都是用“==”来进行比较的。一直没注意这个问题,今天遇到了吓一大跳。庆幸过去的程序中用“==”没出现问题。把源码拖出来看了一下,明白了,解释如下:
平常我们使用Integer a = xxx;的时候,Integer类实际上是调用的是public static Integer valueOf(int i)方法。这个方法是这样的。
view
plaincopy
to clipboardprint?publicstaticIntegervalueOf(inti){finalintoffset=128;if(i>=-128&&i<=127){//mustcachereturnIntegerCache.cache[i+offset];}returnnewInteger(i);}
从上面代码可以看出,当进行赋值操作时,Java将这个值分为两个区间来处理,即:
i 属于[-128, 127]的时,返回IntegerCache.cache[i + offset];
i 属于上面范围以外时,返回new Integer(i)。
上面实例程序中,赋值超出[-128, 127]返回,所以返回为new Integer(1000),而“==”比较是比较内存地址,那么返回值肯定为FALSE。
至此上面陈述的诡异问题就解开了。
但是Java为什么要这样分区间处理呢,这不是使劲儿把我们往误区里勾引吗?为此我测试了这样一个程序:赋值在[-128, 127]之间时。
view
plaincopy
to clipboardprint?publicclassTest{publicstaticvoidmain(String[]args){Integera=10;Integerb=10;System.out.println("a==b:"+(a==b));System.out.println("a.equals(b):"+a.equals(b));}}
这段代码的输出结果是这样的:
view
plaincopy
to clipboardprint?a==b:truea.equals(b):true
为什么出现这种现象呢?这就要问IntegerCache.cache[i + offset]了,跟踪进去代码如下:
view
plaincopy
to clipboardprint?staticfinalIntegercache[]=newInteger[-(-128)+127+1];static{for(inti=0;i<cache.length;i++)cache[i]=newInteger(i-128);}
也就是说,当赋值在[-128, 127]区间时,Java是从同一个数据中取出同一个对象,即内存地址一样,所以“==”操作返回TRUE;
那么猜测Java这样做的目的,可能[-128, 127]区间比较常用,这个区间内的Integer对象也作为静态变量初始化完成,这样直接返回对象可以提高效率。
为了防止不小心掉入这样的陷阱,对于基本类型的比较,用“==”;而对于基本类型的封装类型和其他对象,应该调用public boolean equals(Object obj)方法(复杂对象需要自己实现equals方法)。
分享到:
相关推荐
JAVA Integer == equal 比较 doc 比较大小 是否相等
细数java中Long与Integer比较容易犯的错误总结.docx
本文主要介绍了Java Integer两种转int方法比较。具有很好的参考价值,下面跟着小编一起来看下吧
主要给大家介绍了Java中long类型与Long类型区别和大小比较的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
一劳永逸让VB自动改变控件大小 Private Sub Form_Load()//初始化设置 Picture1.AutoSize = True Command1.Caption = ″显示网格″ Command2.Caption = ″取消网格″ Form1.Caption = ″显示网格图像演示程序...
hWndC = capCreateCaptureWindowA('My Own Capture Window',1342177280,0,0,200,150,THISFORM.HWND ,0) &&显示大小 IF hWndC <> 0 SendMessage(hWndC, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0) SendMessage(hWndC, ...
Dim H, i As Integer On Error Resume Next Resize_ALL Me 'Me是窗体名,Form1,Form2等等都可以 End Sub 在模块中添加以下代码: Public Type ctrObj Name As String Index As Long Parrent As String Top As...
FLetterKeyWidth: Integer; //字母按键宽度 FLetterKeyHeight: Integer; //字母按键高度 FNumberKeyWidth: Integer; //数字按键宽度 FNumberKeyHeight: Integer; //数字按键高度 FShiftKeyWidth: Integer;...
Integer 否 否 0-未删除,1-删除 UserImage 用户照片 varchar(50) 否 否 用户头像 Status 是否在线 Integer 否 否 0-离线1-在线2-忙碌3-离开 2、人事档案表(personalfile) 字段名称 字段含义 字段大小 是否为空 是否...
//MBR + 主分区表的大小 + 备用分区表的大小 pDliEx2->Gpt.DiskId = pCd->Gpt.DiskId; pDliEx2->Gpt.MaxPartitionCount = 128; pDliEx2->Gpt.StartingUsableOffset.QuadPart = (34 * 512)...
iThreadCount : Integer; //线程数 aGauge : TGauge; // 进度条 procedure StartJob; // 初始化并开始下载 procedure StopJob; // 停止下载 procedure GetProgressInfo; // 获取下载进度信息 ...
说明:WizModernImage.bmp这个图片的大小为:164×314 WizModernSmallImage.BMP这个图片的大小为:55×55 (这2个图片大小 我是按照以前默认大小改的,其它比例大小我没试过,有兴趣的话可以自己试下。)
版本处理类,提供版本与数字互相转换,方便入库后进行比较筛选 * Func: * public version_to_integer 将版本号转为数字 * public integer_to_version 将数字转为版本号 * public check 检查版本格式是否正确 * ...
目前提供了 32 位和 64 位整数加密/解密,但它足够通用,可以应用于任何整数大小。 要使用此库,您可以包含所需的库源或将其用作静态或动态库。 请参阅测试文件夹中的演示文件。 API 很简单。 您使用您的秘密密钥...
Sql代码 代码如下: — Created on 2010/04/17 by NAN declare — Local variables here i integer; v_date1 DATE; v_date2 DATE; begin — Test statements here v_date1 := SYSDATE; v_date2 := to_date( ‘2008-09...
" 4、角色权限表(RoleRight) "字段名称 "字段含义 "字段大小 "是否为空"是否外键 "说明 " "RoleRightId "角色权限id "Integer "否 "否 "角色权限id " "RoleId "角色id "Integer "否 "是 "外键,RoleInfo的RoleId " ...
function Integer GetScreenBMP(Integer x1,Integer y1,Integer x2,Integer y2,String FileName) library 'extlib.dll' ALIAS FOR "GetScreenBMP;Ansi" //根据窗口句柄抓图保存为BMP function Integer GetWindowBMP...
Delphi 设置打印纸张大小,手动设置打印纸的长度和宽度,自定义纸张。相关代码: procedure TForm1.SetPaperSize(cx, cy: Integer); var a,b,c: array[0..255]of char; bb: Cardinal; ee: PDEVMODE; ...
实现了实现了原来控件中没有的、很多人梦寐以求的功能:鼠标事件,键盘事件,自定义菜单,动画原来大小,及扩展的动画信息... 开发工具: VB6.0企业版 免费控件 Email:yztink@163.com 主 页:...