`
ihyperwin
  • 浏览: 434654 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Long == 操作符 的陷阱

阅读更多

当两个对象进行比较的时候,我们应该使用equals方法,但是由于基础类型在1.5以前的jdk,大家已经习惯了 == 的方式,所以有时候,会马虎大意依然使用 ==  进行比较,那么这样会有什么问题吗?结果是什么?

1
2
3
4
5
6
7
8
9
10
11
Long a2 = 127L;
Long b2 = 127L;
System.out.println(a2 == b2);
 
结果是true,竟然是true???
 
Long a3 = 128L;
Long b3 = 128L;
System.out.println(a3==b3);
 
结果是false

这样结果的原因是Long类型内部有一个内部类,维护了一个cache,

见Long源码 552行

1
2
3
4
5
6
7
public static Long valueOf(long l) {
    final int offset = 128;
    if (l >= -128 && l <= 127) { // will cache
        return LongCache.cache[(int)l + offset];
    }
        return new Long(l);
}

见Long源码 528行

1
2
3
4
5
6
7
8
9
10
private static class LongCache {
    private LongCache(){}
 
    static final Long cache[] = new Long[-(-128) + 127 + 1];
 
    static {
        for(int i = 0; i < cache.length; i++)
        cache[i] = new Long(i - 128);
    }
    }

-128到127直接的值都放在cache里,不会创建新的对象,所以==比较的时候,结果是正确的,

当超过这个范围,因为是创建的新对象,所以自然不会相等

分享到:
评论

相关推荐

    C++程序设计陷阱 .

    此外,避免使用原始的new和delete操作符,而应使用RAII(Resource Acquisition Is Initialization)原则,如使用std::vector和std::string等容器。 函数参数传递也是需要注意的地方。C++支持值传递、引用传递和指针...

    通过实例了解Java Integer类和int的区别

    Long类型的比较和Integer类型的比较类似,也需要使用equals()方法,而不是==操作符。 知识点7:缓存机制 Java中的Integer和Long类型都有缓存机制,在一定范围内的值会被缓存,以提高性能。 知识点8:自动拆箱和...

    C++sizeof使用规则及陷阱分析

    3. **表达式求值**:当 `sizeof` 操作符应用于表达式时,表达式的求值发生在编译期,且只计算表达式中各个变量或常量的类型。 - 示例: ```cpp int a = 0; cout (a = 3) ; // 输出 int 类型的大小 ``` #### 三...

    C规范-数据类型 规范 陷阱

    ### MISRA C规范之数据类型陷阱详解 #### 一、引言 在计算机科学领域,尤其是在嵌入式系统开发中,MISRA C规范成为确保软件质量和可靠性的关键指南之一。该规范尤其强调了在使用C语言编程时,正确处理数据类型的...

    C语言陷阱解读

    strcpy(buf, "This string is too long!"); // 缓冲区溢出 ``` ##### 6.2 内存管理错误 动态内存分配和释放的错误是C语言中最常见的问题之一。例如,忘记释放内存或重复释放同一块内存都会导致程序崩溃或内存泄漏...

    java解惑

    这意味着,当使用取余操作符时,结果与左操作数具有相同的符号。因此,当`i`为负奇数时,`i % 2`的结果为-1而非1,导致方法错误地返回`false`。 为了避免此类陷阱,应确保方法能够正确处理负数、零和正数。修正后的...

    V20-Java笔记整理-重要概念和常见陷阱梳理.docx

    - 使用`==`操作符比较字符串引用是否相等。 **7.5 包装类、基本数值类型和字符串之间转换关系** - **基本数值类型转换为包装类**:使用对应的包装类的构造函数。 - **包装类转换为基本数值类型**:使用包装类的`xxx...

    Java 面试中的陷阱

    而`s1 += 1`是正确的,因为这是复合赋值操作符,会自动处理类型转换。 12. **sleep() 和 wait()**:`sleep()`使当前线程暂停指定时间,不会释放锁;`wait()`使线程等待,释放对象锁,等待其他线程唤醒。 13. **...

    Java解惑(中文).pdf

    #### 表达式谜题和取余操作符(%)的理解 在Java中,取余操作符(%)用于返回两个数相除的余数。按照定义,对于任何整数`a`和任何非零整数`b`,`(a/b)*b+(a%b)`的值应等于`a`。然而,在实际使用中,需要注意取余...

    Java解惑(中文版)[JAVA的细节]

    1. **取余操作符(%)的行为**:在Java中,取余操作符(`%`)的行为遵循一种特殊的规则。对于所有的整数`a`和非零整数`b`,满足等式 `(a / b) * b + (a % b) == a`。这意味着,取余操作返回的余数的正负号总是与左边...

    java 解惑 挺多java方面的迷题

    此外,如果性能是关键因素,可以使用位操作符`&`代替取余操作符,以提高效率: ```java public static boolean isOdd(int i){ return i % 2 != 0; // 更正后的判断条件 } // 或者使用位操作符 public static ...

    Java解惑(中文+书签).pdf

    1. 取余操作符(%)的特性与陷阱 在Java中,取余操作符(%)用于计算两个整数相除的余数。例如,`i % 2` 将会返回整数`i`除以2后得到的余数。但在处理负整数时,该操作符的返回值会保留与左侧操作数相同的符号。这...

    Java面试中的陷阱

    `则不会导致错误,因为`+=`操作符会自动进行类型转换。 #### 十一、sleep()与wait()的区别 - **sleep()**:使当前线程暂停指定的时间,然后恢复。它属于`Thread`类的方法,不释放锁。 - **wait()**:使当前线程...

    Java核心基础+Java中的数据在内存中的存储

    `==`操作符用于比较两个对象的引用是否相等,而`equals()`方法用于比较两个对象的内容是否相等。例如: ```java String s1 = "hello"; String s2 = new String("hello"); System.out.println(s1 == s2); // 输出 ...

    C++ sizeof 使用规则及陷阱分析

    它并不是一个函数,而是一个在编译时进行计算的操作符,这意味着它在程序运行之前就已经确定了结果。`sizeof`的返回值是`size_t`类型,表示字节数。 在描述中,通过比较`struct s1`和`struct s2`的大小,我们可以...

    java解惑文档

    首先,关于奇偶判断的问题,Java中的取余操作符(%)是一个容易被误解的工具。该操作符用于计算两个整数相除的余数,但是其结果的正负符号,会与被除数的符号相同。这一点在判断奇偶性时显得尤为重要。在Java中,一...

    改善Java程序的151个建议

    **案例解析**:书中通过一个具体的示例展示了当三元操作符的两个分支返回类型不一致时,可能出现的问题。即使条件判断的结果指向了相同类型的值,但由于另一个分支的存在,编译器可能会选择更宽泛的类型进行转换,...

    java谜题中文版

    Java的取余操作符 `%` 的行为,在负数参与运算时,与预期不符。具体而言,当`i`为负奇数时,`i % 2`的结果是-1,而非1。这是因为Java中`%`的操作符设计使得其结果与左侧操作数同号。即,如果`a`和`b`满足以下等式: ...

    深入Java关键字null

    1. **判断一个引用类型数据是否为null**:通常使用`==`操作符来进行判断。 2. **释放内存**:让一个非`null`的引用类型变量指向`null`。这样做会使该对象不再被任何引用所持有,从而使其成为垃圾回收的目标。 综上...

Global site tag (gtag.js) - Google Analytics