if (a == 1 && a == 2 && a == 3) 为 true,你敢信???

点击关注公众号,Java 干货及时推送↓

推荐阅读:年中的 Java 招聘市场已经疯掉了...

大家好,我是R哥。

最近看到一个非常离谱的骚操作:一个对象,竟然能同时等于两个不同的值,比如你写 JS 代码 if (obj == 10 && obj == 100),它居然能满足两个条件并打印出结果。

第一次看到这个代码,我脑袋嗡嗡的,就两个字:离谱

抱着好奇的精神研究了一番,当我搞懂背后的机制,才发现这其实是一种 巧妙利用语言特性的黑魔法,而且不仅在 JavaScript 中能玩出花来,Java 也能曲线救国整出个类似效果。

这篇文章就带大家从 JS 到 Java,掘地三尺把这个骚操作背后的本质讲清楚。

Javascript 版实现

如以下 Javascript 代码:

// 公众号:Java技术栈
var obj = {
i: 10,
valueOf: function() {
    if (this.i === 10) {
      this.i++;
      return10;
    } else {
      return100;
    }
  }
}
if (obj == 10 && obj == 100){
    console.log(obj);
}

输出结果:

{ i: 11, valueOf: [Function: valueOf] }

这里的 if (obj == 10 && obj == 100) 判断居然能同时满足?

其实这是利用了 valueOf 的可变返回值,第一次返回 10,第二次返回 100,所以 obj 可以做到同时等于两个不同的值!

这个对象 obj 有一个属性 i 和一个自定义的 valueOf 方法。

当你对一个对象进行如 obj == 10 这样的 非严格比较 时,JavaScript 会调用该对象的 valueOf() 方法(如果没找到,会再尝试 toString())。

第一次:obj == 10

此时 obj.valueOf() 被调用:

if (this.i === 10) { // true
  this.i++;          // i 变成 11
  return 10;         // 返回 10
}

于是 obj == 10 => 10 == 10 => ✅ 成立!

第二次:obj == 100

再次触发 obj.valueOf()

if (this.i === 10) { // false,因为 i 已经是 11
  ...
} else {
  return 100;
}

返回 100,所以 obj == 100 => 100 == 100 => ✅ 成立!


我们还可以拓展一下更骚的写法:

let obj = {
  i: 1,
  valueOf() {
    return this.i++;
  }
};

if (obj == 1 && obj == 2 && obj == 3) {
  console.log("骚操作成功!");
}

输出结果:

骚操作成功!

Java 版实现

上面那个 JS 代码的核心是利用了对象的 valueOf() 方法在 == 比较中的自动调用,每次返回不同的值,从而实现了一个对象同时等于多个不同的值。

但在 Java 中并不能直接重载 == 的行为,因为 Java 中 == 比较的是 引用地址(对象)或基本类型的值,而不能像 JS 那样 “自动调用某个方法” 来参与比较。

不过,我们可以方法 + 状态变量实现类似的效果:

/**
 * 公众号:Java技术栈
 */
publicclass Test {

    privateint i = 10;

    public boolean equalsTo(int value) {
        if (i == 10) {
            i++; // i 从 10 -> 11
            return value == 10;
        } else {
            return value == 100;
        }
    }

    @Override
    public String toString() {
        return"MagicObject{i=" + i + "}";
    }

    /**
     * 公众号:Java技术栈
     */
    public static void main(String[] args) {
        Test obj = new Test();

        // 模拟 JS 的 a == 10 && a == 100
        if (obj.equalsTo(10) && obj.equalsTo(100)) {
            System.out.println(obj);
        } else {
            System.out.println("条件不满足");
        }
    }

}

输出结果:

MagicObject{i=11}

Java 版本也可以拓展一下更骚的写法:

/**
 * 公众号:Java技术栈
 */
publicclass Test {

    privateint val = 1;

    public boolean equalsTo(int input) {
        return input == val++;
    }

    public static void main(String[] args) {
        Test obj = new Test();

        if (obj.equalsTo(1) && obj.equalsTo(2) && obj.equalsTo(3)) {
            System.out.println("骚操作成功!");
        }
    }

}

输出结果:

骚操作成功!

哈哈,虽然两种语言的实现原理不同,但思路一致,背后都是对 “状态变化 + 比较逻辑” 做了精心设计。

话说,这种代码有啥用?

说实话,你如果在真实项目中写出这种防御性骚代码,多半会被群起而攻之。但在面试、比赛、写博客、讲技术、装逼的时候,可能会是个绝活。

所以别只会看热闹,背后的机制才是我们真正要掌握的。

好了,今天的分享就到这里了,后面R哥会分享更多好玩的 Java 技术和最新的技术资讯,关注公众号Java技术栈第一时间推送。

版权声明: 本文系公众号 "Java技术栈" 原创,转载、引用本文内容请注明出处,抄袭、洗稿一律投诉侵权,后果自负,并保留追究其法律责任的权利。


↓↓↓点下面小程序刷题突击面试↓↓↓

推荐阅读:

1. Java 24 正式发布,超神了。。。

2. Spring Boot 3.5 正式发布,王炸级更新!

3. Spring AI 1.0 发布,让 Java 再次伟大!

4. 现在的 Java 行情,没人能轻松通过面试。

5. 什么情况,今年面试都不问八股文了??

6. 面试了个 7 年 Javaer,真让我哭笑不得!

7. 面试通过,背调凉凉。。

8. Spring Boot 3.x 又又又更新了!

9. Spring Cloud 微服务实战(2025 最新版)

10. 2025 全新 Java 面试题(3000+)

关注公众号学习最主流的 Java 技术↓

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java技术栈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值