`
小野bupt
  • 浏览: 14807 次
  • 性别: Icon_minigender_1
文章分类
社区版块
存档分类
最新评论

Integer大小的比较

 
阅读更多

原文地址: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:false
a.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){//mustcache
returnIntegerCache.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:true
a.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 中的 Integer 比较 在 Java 中,我们经常需要比较两个 Integer 对象是否相等,但是在使用 "==" 运算符时,可能会出现一些意外的结果。本文将深入探讨 Java 中的 Integer 比较,了解为什么使用 "==" 运算符可能...

    JAVA-int和Integer的区别

    此外,`Integer`类还提供了一些实用方法,比如`parseInt()`用于将字符串转换为整数,`toString()`用于将整数转换为字符串,以及`compareTo()`用于比较两个`Integer`对象的大小。 总的来说,`int`适合于需要高性能...

    Integer类的使用方法

    - **比较方法**:如`compareTo(Integer anotherInteger)`用于比较两个`Integer`对象的大小。 - **获取值的方法**:如`intValue()`, `longValue()`, `floatValue()`, `doubleValue()`用于获取`Integer`对象的不同数值...

    细数java中Long与Integer比较容易犯的错误总结.docx

    ### Java中Long与Integer比较易犯错误总结 #### 一、引言 在Java编程过程中,经常需要对数值进行比较操作。对于基本数据类型如`int`和`long`,可以直接使用`==`进行比较。然而,当涉及到它们的包装类`Integer`和`...

    Java中Integer两种转int方法比较

    这个方法通常在你需要使用`Integer`对象的特性(如缓存、比较操作或泛型方法参数)时使用。 在面试或笔试题中,如题目所示,`a = Integer.parseInt("123")`会将字符串"123"解析为`int`类型的值,并赋给变量a,所以a...

    big integer

    在编程领域,大整数(Big Integer)是指能够表示超出普通整型变量范围的非常大的数值。在C++中,由于标准库并没有内置大整数类型,因此在处理需要存储和操作大整数的场景时,程序员通常需要自定义一个大整数类。标题...

    比较大小(VB6.0代码编写)

    在VB6.0编程环境中,比较大小是基本的操作,它涉及到条件判断和逻辑运算。VB6.0(Visual Basic 6.0)是Microsoft推出的一种可视化编程工具,它支持多种数据类型,包括数值型、字符串型等,因此比较操作可以应用在...

    c++ 大整数库 big integer

    此外,还可能有位操作(如左移和右移)以及比较操作。 4. **性能优化**:对于大整数运算,效率至关重要。高效的算法(如Karatsuba乘法、Toom-Cook算法或者更高级的FFT方法)可能被用来加速乘法。同时,减法、除法和...

    将 BigDecimal 类型转换为 Integer 类型.pdf

    BigDecimal 类型是 Java 提供的一种用于精确算术运算的类,它支持任意大小的十进制数,并且能够避免浮点数计算时可能出现的舍入误差。然而,有时我们需要将这些大数转换为整数类型,如 Integer,以便于存储或者进行...

    Java中long类型与Long类型的区别和大小比较详解

    Java中long类型与Long类型的区别和大小比较详解 在Java中,long类型和Long类型都是用于表示数字的数据类型,但是它们之间存在着一定的区别。long类型是基本数据类型,而Long类型是对象类型,本文将通过示例代码详细...

    定义比较器,比较数组中值大小

    本文将深入探讨如何定义比较器来比较数组中值的大小,并通过一个具体的示例进行说明。 首先,我们需要了解Java中的Comparator接口。Comparator接口提供了一个方法`compare(T o1, T o2)`,用于比较两个对象的顺序。...

    Integer IntegerCache源码阅读

    在Java编程语言中,`Integer` 类是 `int` 基本类型的包装类,它提供了许多额外的功能,如比较、格式化等。当我们使用 `Integer.valueOf()` 方法将字符串或整数值转换为 `Integer` 对象时,Java会进行一些优化以提高...

    比较Max and min大小

    在编程领域,比较大小是日常任务之一,无论是在算法实现、数据处理还是逻辑判断中都不可或缺。本主题将深入探讨如何在Java编程语言中比较两个数值(最大值和最小值)的大小。Java提供了多种方法来执行这种比较,包括...

    Large-integer.rar_ large integer_integer加减乘除_visual c

    这种表示方式允许我们处理任意大小的整数,但同时也引入了额外的计算复杂性。 在大整数的加法和减法中,我们可以采用类似于纸笔计算的方法,从低位到高位逐位进行操作。如果某位相加或相减的结果超过单个位的范围,...

    窗体控件大小随窗体大小变化而变化

    在VB(Visual Basic)编程环境中,我们经常需要创建具有动态特性的用户界面,其中窗体控件的大小能够根据窗体自身的大小变化而自动调整,以保持良好的视觉效果和用户体验。这种功能通常被称为“自适应布局”或“响应...

    long-integer-additions-operations.zip_long-integer

    在计算机科学中,长整数(Long Integer)处理是针对那些超出普通整型变量范围的大整数进行计算的需求。在“long-integer-additions-operations.zip_long-integer”这个资源中,重点讲述了如何使用双向循环链表和数组...

    易语言获取文件夹大小源码 非FSO对象

    `GetFileSizeEx`函数通常用于获取单个文件的大小,它返回一个`ULARGE_INTEGER`类型的值,这个类型可以存储非常大的文件大小,包括大于4GB的文件。但是,描述中提到的问题在于开发者可能对如何正确处理这个大整数不太...

    Gaussian Integer

    ### 高斯整数(Gaussian Integer) 高斯整数是在复数域中对整数概念的一种扩展,由数学家卡尔·弗里德里希·高斯引入。它们在数论中有着重要的应用,并且与传统的整数有诸多相似之处。高斯整数集记为 \(\mathbb{Z}[i]...

    convert string to integer

    `Fixnum`表示固定大小的整数,通常在不溢出的情况下可以直接进行算术运算。在Ruby 2.4之后,`Fixnum`和`Bignum`合并成一个新的类`Integer`,涵盖了所有整数范围。 现在让我们看看`string_to_integer.rb.txt`文件中...

    delphi7获取文件大小

    I: Integer; FileInfo: TSearchRec; begin Result := 0; if not DirectoryExists(DirPath) then Exit; // 获取目录中的所有文件 Files := TDirectory.GetFiles(DirPath); for I := 0 to High(Files) do ...

Global site tag (gtag.js) - Google Analytics