三目运算符_不是吧,还有人不知道三目运算符的BUG

三目运算符一直是众多开发者信手拈来的一种写法,它简化了if-else的臃肿的写法,而是用一行代码替代,就感觉无形之中秀了一把。

8520b5877f48f31d2802b6f051fcca75.png

殊不知,这么帅气的代码也暗藏着一个BUG。

缘由

头天晚上发布了一个功能,本以为是波澜不惊的一个需求,结果第二天kibana打出了成吨的NPE日志。这些NPE日志大多都不约而同都指向了我写的一行代码,我立马推了下我的眼镜,开始排查起来了。

fc3ad9f9f07d3eb1d2e1fdadca0de4f2.png

问题代码

77d72f6308cd6806f18e10ff3c65b173.png

Kibana的堆栈日志定位在第899行。

resultMap.put("unAuditPurchaseOrder", switchConf == null ? 0 : switchConf.getUnAuditPurchaseOrder());

1.检查了resultMap,它在上面有实例化,不可能为空。

2.检查switchConf,但是在这里有判空,也不会报错。 那是怎么回事????

d64a33c7180f40ad61a87b2c14c7a08e.png

继续排查

既然肉眼看不出,那么只能找一台测试机,用一下Arthas看一下具体的情况。(线上慎用,因为可能会造成卡顿)

trace com.raycloud.dmj.tj.services.customer.CustomerButtonService getPurchaseConfig -n 5 '1==1' --skipJDKMethod false

b65cab25cf329fc91a4f4bf031615eec.png

果然,这里就发现了端倪。 这里竟然执行了intValue()!也就是说如果switchConf.getUnAuditPurchaseOrder()这个是null,那么就很明显发生了NPE。

看一下字节码

为了显现效果,我换一个简单的程序

public class Test {

    public static void main(String[] args) {

        Integer i = null;
        System.out.println(1 != 1 ? 0 : i);

    }
}

定位到class文件目录,执行

javap -c -l Test

5440ddb1e74de0efb5dca6643e8f8a93.png

然后我又改了一下程序

public class Test {

    public static void main(String[] args) {

        Integer i = null;
        System.out.println(1 == 1 ? 0 : i);

    }
}

这次运行并不会报错,看一下它的JVM指令:

f4adb5672d0f5d22810e203753b964a8.png

因为三目运算符的结果是前者的逻辑,即返回一个常量0。


解释


由上面的实验可以发现,JVM在解释三目运算符的时候,会对两个逻辑语句进行数据类型校验,按照前者的数据类型为准。实验中,数据类型是基本数据类型,所以,如果逻辑走到了后者,那么就会进行自动的拆箱。这个隐式的操作就是造成这个BUG的原因。

9e7dbae5b4da473747cff21324af5a51.png


解决

既然知道原因了,那么只要统一数据类型就行:

public class Test {

    public static void main(String[] args) {

        Integer i = null;
        System.out.println(1 != 1 ? new Integer(0) : i);

    }
}

然后按照惯例,我们还是看一下他的JVM指令:

345edf017e34eb2cbffc783c742f078d.png

拾遗

后来在无意之中发现,原来这个例子在《阿里巴巴开发手册》当中也有被记录

349a7fb8195a963af77940b401cd16c2.png

其实说的也是一回事情!

后续

最后,虽然问题是解决了,但我还是被测试同学记录了一下黑名单,这锅得背~

原文:不是吧,还有人不知道三目运算符的BUG - 掘金
作者: 浮沉_fuchen
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图像识别技术在病虫害检测中的应用是一个快速发展的领域,它结合了计算机视觉和机器学习算法来自动识别和分类植物上的病虫害。以下是这一技术的一些关键步骤和组成部分: 1. **数据收集**:首先需要收集大量的植物图像数据,这些数据包括健康植物的图像以及受不同病虫害影响的植物图像。 2. **图像预处理**:对收集到的图像进行处理,以提高后续分析的准确性。这可能包括调整亮度、对比度、去噪、裁剪、缩放等。 3. **特征提取**:从图像中提取有助于识别病虫害的特征。这些特征可能包括颜色、纹理、形状、边缘等。 4. **模型训练**:使用机器学习算法(如支持向量机、随机森林、卷积神经网络等)来训练模型。训练过程中,算法会学习如何根据提取的特征来识别不同的病虫害。 5. **模型验证和测试**:在独立的测试集上验证模型的性能,以确保其准确性和泛化能力。 6. **部署和应用**:将训练好的模型部署到实际的病虫害检测系统中,可以是移动应用、网页服务或集成到智能农业设备中。 7. **实时监测**:在实际应用中,系统可以实时接收植物图像,并快速给出病虫害的检测结果。 8. **持续学习**:随着时间的推移,系统可以不断学习新的病虫害样本,以提高其识别能力。 9. **用户界面**:为了方便用户使用,通常会有一个用户友好的界面,显示检测结果,并提供进一步的指导或建议。 这项技术的优势在于它可以快速、准确地识别出病虫害,甚至在早期阶段就能发现问题,从而及时采取措施。此外,它还可以减少对化学农药的依赖,支持可持续农业发展。随着技术的不断进步,图像识别在病虫害检测中的应用将越来越广泛。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值