V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
butterflyzh
V2EX  ›  问与答

为什么 Java 的 Long.equals 的方法不能兼容 Integer 呢?

  •  
  •   butterflyzh · 2022-04-09 10:17:48 +08:00 · 2269 次点击
    这是一个创建于 962 天前的主题,其中的信息可能已经有所发展或是发生改变。
    例如:Long val1 = new Long(10000L);
    Integer val2 = new Integer(10000);
    val1.equals(val2);
    应该期望是返回 true 啊,但是返回的 false 。这算是 JDK 的 bug 吗
    17 条回复    2022-04-11 14:57:57 +08:00
    redford42
        1
    redford42  
       2022-04-09 10:22:30 +08:00
    equals 不重写进行地址比较
    falsemask
        2
    falsemask  
       2022-04-09 10:31:03 +08:00
    ```
    public boolean equals(Object obj) {
    if (obj instanceof Long) {
    return value == ((Long)obj).longValue();
    }
    return false;
    }
    ```
    GuuJiang
        3
    GuuJiang  
       2022-04-09 10:53:58 +08:00 via iPhone   ❤️ 9
    假如兼容了的话会违背自反性,即 a.equals(b) == b.equals(a)
    MakHoCheung
        4
    MakHoCheung  
       2022-04-09 11:56:17 +08:00
    值类型和引用类型 eq 的区别
    zpxshl
        5
    zpxshl  
       2022-04-09 15:07:19 +08:00 via Android
    应该期望是返回 true 吗
    强行预期
    otakustay
        6
    otakustay  
       2022-04-09 16:25:09 +08:00
    比如你的逻辑是判断一个数和自己的一个 magic number 是否一样,一样的话给它加上 65536 ,很好一个 Integer 和你的 magic Long 一样,于是你加了,于是程序崩了
    loshine1992
        7
    loshine1992  
       2022-04-09 16:47:28 +08:00
    JDK Long 的源码

    ```java
    public boolean equals(Object obj) {
    if (obj instanceof Long) {
    return this.value == (Long)obj;
    } else {
    return false;
    }
    }
    ```
    jsdi
        8
    jsdi  
       2022-04-09 17:37:04 +08:00
    个人理解,因为 equal 进行对象比较,对象的类型必须一直才有意义,Long 和 Integer 属于不同的类。
    msaionyc
        9
    msaionyc  
       2022-04-09 18:32:34 +08:00 via iPhone
    如果你非要这样,可以自己写个 numberutil 。
    Jooooooooo
        10
    Jooooooooo  
       2022-04-09 18:47:25 +08:00
    所以你的期望是错的呗.
    AllenHua
        11
    AllenHua  
       2022-04-09 18:49:26 +08:00
    Java 强类型语言,所以源码里一开始的判断就是用的 instanceof 关键字。类型都不一样肯定会返回 false 了,类型一样才会进一步比较值是否相等
    kx5d62Jn1J9MjoXP
        12
    kx5d62Jn1J9MjoXP  
       2022-04-09 21:27:09 +08:00 via Android
    其实是可以的,只是没有这样做
    abc612008
        13
    abc612008  
       2022-04-09 21:47:23 +08:00   ❤️ 1
    @zpxshl @Jooooooooo 从使用者(新用户)直觉角度来说,1L 难道不应该等于 1 吗?这就和 Java 字符串没法直接相等一样,是很反直觉的设计。你要是不想和 C++一样搞隐性类型转换,也可以和 Kotlin 一样直接报错啊。直接返回 false 算什么预期。

    你要是遇到一个没见过的语言,写了个 "1"=="1" 或者 1 == 1L 你会下意识觉得这是 false ?
    EscYezi
        14
    EscYezi  
       2022-04-11 00:52:19 +08:00 via iPhone
    It’s a feature,not a bug.
    bigbyto
        15
    bigbyto  
       2022-04-11 14:45:21 +08:00
    @GuuJiang 额..你例子说的没错,不过这个是对称性。自反是 x.equals(x) == true 。
    bigbyto
        16
    bigbyto  
       2022-04-11 14:51:30 +08:00
    等价关系也称为同值关系(英语:Equivalence relation )即设 R 是某个集合 A 上的一个二元关系。若 R 满足以下条件:

    自反性:xRx
    对称性:xRy ==> yRx
    传递性:xRy, yRz, xRz

    上面就定义了 R 是某个集合 A 上的一个二元关系,但 Integer 和 Long 实际上是 2 个集合,可以理解为不同的东西,不具备等价关系。 比如 2147483648 在 Integer 就无法表达。
    GuuJiang
        17
    GuuJiang  
       2022-04-11 14:57:57 +08:00 via iPhone
    @bigbyto 是的,口误了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3251 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 00:39 · PVG 08:39 · LAX 16:39 · JFK 19:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.