Java互联网科技程序员

一起来看装箱引发的线上问题

2020-09-19  本文已影响0人  小美人鱼失去的腿

背景

客服同学反馈使用某功能时,页面提示异常。

像往常一样,小伙伴积极响应,按部就班的先翻日志,找到异常信息,定位到哪一块范围,然后就...(给出反馈结果)

小伙伴看了小一会儿,怎么看都感觉没有问题,正准备赶班车之际,小伙伴喊渣渣勇也看下这段逻辑,大概瞄了两眼确实没发现问题(主要还是太菜了),就先撤了...

以下内容暂不讨论代码编写规范问题...

正文

1、一筹莫展

路上回想那段逻辑,好像确实没什么问题... 坚信勤能补拙的渣渣勇,回来后还是决定翻下代码

翻了下线上异常日志信息:

image.png

看到这日志信息,这不是很明显,类名 + 行数 都提示了嘛... 按常规套路,翻出对应代码... (需确保代码跟线上版本一致)

异常 563行 逻辑如下:

image.png

这么看,好像这行代码确实没什么问题(其实这里有很大问题!

后面想线上跟本地打的包不一致导致,down了对应的class文件下来,如红色框所示:

image.png

这就很奇怪了,难道真的是代码有毒?

2、峰回路转

事到如今,也只好拔出我的大杀器,40米长的大刀 -- Arthas !

trace 一下对应的方法,页面再模拟请求下:

image.png

ok,很明显,空指针出来了!

再使用 jad 命令反编译对应方法 (由不得感叹arthas 真香):

image.png

看到红色框所示,由不得感叹一声,what the help (Fxxx)?

到这里,原因已经很明显了, 当对象不为空、属性为空时,就会出现 NPE;

应该有小伙伴跟我一样会有疑问,为什么反编译会多出来 Integer.value; OK,其实就是图二中的 DEFAULT 搞得鬼!

private static final int DEFAULT = 0;

因为对象用的是 Integer,涉及到装箱的操作,所以会多出 Integer.value 方法;(这里体现出打的包中的 class 文件多么不靠谱)

3、问题复现

为了验证以上问题,写了个demo来复现一下:

/**
 * Author : bingo624
 * Date : 2020/9/17 23:23
 * Description :
 * version : 1.0
 */
@RestController
public class HelloController {

    private static final int DEFAULT = 0;

    @RequestMapping("/hello1")
    public StudentVo hello1(){
        PhxUserDto phxUserDto = new PhxUserDto();
        StudentVo vo = new StudentVo(phxUserDto == null ? DEFAULT : phxUserDto.getGender());
        return vo;
    }

    @RequestMapping("/hello2")
    public StudentVo hello2(){
        PhxUserDto phxUserDto = new PhxUserDto();
        StudentVo vo = new StudentVo(phxUserDto == null ? null : phxUserDto.getGender());
        return vo;
    }

    @RequestMapping("/hello3")
    public StudentVo hello3(){
        PhxUserDto phxUserDto = new PhxUserDto();
        StudentVo vo = new StudentVo(phxUserDto == null ? Integer.valueOf(0) : phxUserDto.getGender());
        return vo;
    }
}

结合上述介绍,猜猜看,是否都能正常返回?

聪明如你,不出所料, 请求 /hello1 是会出现 NPE 返回 500

image.png

/hello2 和 /hello3 都是能正常响应的!

最后来看看打的jar包中的class文件,以及线上反编译后的类:

jar包中的class文件:

image.png

线上反编译后:

image.png

4、柳暗花明

翻了下阿里规约:(拆箱装箱都有可能引发 NPE)

image.png

官网指引: docs.oracle.com/javase/spec…

image.png

总结

通过一个案例,体现出基础知识的重要性;代码编写规范,可以避免很多问题;

犯错误是很正常的,更应该思考的是:出现问题如何通过掌握的各种工具来解决,以及不重复犯错!

最后再安利一波 arthas, 真香!(还有很多高级特性等待你的发掘...)

上一篇 下一篇

猜你喜欢

热点阅读