代码出错了,IDE竟然不报错?太诡异了….


以一
以一 2024-01-07 17:08:13 63507 赞同 0 反对 0
分类: 资源
今天分享一个写代码时遇到的诡异问题,如何排查解决的。 从事互联网的人都懂,一般遇到问题时,首先会想用谷歌、百度等搜索引擎,看看前辈们是如何解决的。 但有些问题比较抽象,不知道如何来描述,怎么办?或者勉强描述清楚了,搜出来的答案也很难满足要求,整个过程犹如大海捞针。最后求助 ChatGPT 瞬间解决,给大家分享下解决思路。

今天分享一个写代码时遇到的诡异问题,如何排查解决的。

从事互联网的人都懂,一般遇到问题时,首先会想用谷歌、百度等搜索引擎,看看前辈们是如何解决的。

但有些问题比较抽象,不知道如何来描述,怎么办?或者勉强描述清楚了,搜出来的答案也很难满足要求,整个过程犹如大海捞针。最后求助 ChatGPT 瞬间解决,给大家分享下解决思路。

问题的来龙去脉

正在开发一个项目,仓储层有一个接口类(IProductReadRepository),其中一个方法的入参使用了 Java 泛型,具体如下:

List batchQuerySpuBySpuIdsFromDB(ProductQueryWrapper req);

在上层的领域服务中,有一处调用这个方法的代码,具体如下:

ProductQueryWrapper productQueryWrapper = ProductQueryWrapper.builder()
        .bizCode(BusinessCodeEnum.SMART.getCode())
        .bizScene(BusinessSceneEnum.RETAIL.getCode())
        .storeId(multiPackageVO.getStoreId())
        .bizParams(spuIds)
        .build();
List productSummaryVOS = productReadRepository.batchQuerySpuBySpuIdsFromDB(productQueryWrapper);

if (CollectionUtils.isEmpty(productSummaryVOS)) {
    bizResult.error(BizErrorCode.MULTI_PACKAGE_PRODUCT_NOT_EXIST);
    return bizResult;
}

其中,List productSummaryVOS = productReadRepository.batchQuerySpuBySpuIdsFromDB(productQueryWrapper); 这行代码非常诡异

返回的结果List并不匹配,但在IDEA中却没有报错,这让我们感到非常困扰。

这是怎么回事?

当时怀疑是错觉,仔细对比了两个方法,确实是对的。

又怀疑是 IDEA 的缓存干扰导致,所以将工程重新 build 了一次还是不行!

接下来,能想到的各种招数都招呼上,比如:

  • 在终端执行 mvn clean install -U,重新编译代码,并强制 Maven 更新所有依赖的快照版本(Snapshot)
  • 手动将 maven 的本地仓库的依赖包全部删除,重新拉取
  • 将本地工程文件中的 target 文件删除
  • …..

最后,使出绝招,将本地的工程代码全部删除,然后重新从 git 上拉取最新代码,编译,导入到 IDEA 工程。

但,但,但,问题依然存在,真让人崩溃。

难道是 IDEA 中的错误检查失效了,于是人为制造了一些错误,发现 IDEA 也都能识别出来。

实在没招了。。。。。。。

最后,还是问下 ChatGPT 吧

首先,先把问题描述清楚,ChatGPT 特懂人情世故,你跟他讲清楚问题,他也会给你一个清楚的答案。

有一个接口内的方法定义如下:

 List batchQuerySpuBySpuIdsFromDB(ProductQueryWrapper req);

使用下面的代码来调用 batchQuerySpuBySpuIdsFromDB,返回的 List 结果并不匹配,但在 IDEA 中没有报错,是什么原因?

ProductQueryWrapper productQueryWrapper = ProductQueryWrapper.builder()
        .bizCode(BusinessCodeEnum.SMART.getCode())
        .bizScene(BusinessSceneEnum.RETAIL.getCode())
        .storeId(multiPackageVO.getStoreId())
        .bizParams(spuIds)
        .build();
List productSummaryVOS = productReadRepository.batchQuerySpuBySpuIdsFromDB(productQueryWrapper);

if (CollectionUtils.isEmpty(productSummaryVOS)) {
    bizResult.error(BizErrorCode.MULTI_PACKAGE_PRODUCT_NOT_EXIST);
    return bizResult;
}

代码出错了,IDE竟然不报错?太诡异了....

ChatGPT 很快就给出了答案。

问题可能出在泛型擦除和编译时类型检查上。由于Java泛型的擦除机制,在运行时无法获取泛型的实际类型,这可能导致类型不匹配的问题。

代码出错了,IDE竟然不报错?太诡异了....

那我们就按照它的思路来,将这行代码  ProductQueryWrapper productQueryWrapper = ProductQueryWrapper.builder()

修改为  ProductQueryWrapper productQueryWrapper = ProductQueryWrapper.builder()

在构建 ProductQueryWrapper 对象时, 指定泛型参数的具体类型,以便在运行时能够正确地识别参数类型。

然后,问题真的解决了。

如下图所示,第二处红框位置的代码开始报错。因为接口的规范(返回结果)调整了,此处确实应该报错提示。

代码出错了,IDE竟然不报错?太诡异了....

后面,我们根据错误提示,将 ProductSummaryVO 类替换成 SpuVO 类。

最终,不但编译不报错,单元测试也能跑通。问题完美解决。

代码出错了,IDE竟然不报错?太诡异了....

背后的原因

为何在 IDEA 中没有直接报错呢?这里牵扯到Java泛型的类型推断机制。

上述代码中,虽然使用了原始类型 ProductQueryWrapper ,但没有指定具体的泛型类型。

Java 7 及以后的版本引入了菱形操作符(Diamond Operator),允许在创建对象时不再重复指定泛型类型,而是通过上下文进行类型推断。

这就意味着在你的代码中,虽然没有明确指定泛型类型,但由于在 ProductQueryWrapper.builder() 上下文中,编译器会尝试根据调用方的期望类型来推断泛型参数。

如果您发现该资源为电子书等存在侵权的资源或对该资源描述不正确等,可点击“私信”按钮向作者进行反馈;如作者无回复可进行平台仲裁,我们会在第一时间进行处理!

评价 0 条
以一L0
粉丝 0 资源 1143 + 关注 私信
最近热门资源
银河麒麟桌面操作系统V10SP1-2403-update1版本中,通过“麒麟管家-设备管理-硬件信息-硬盘”查看硬盘类型时,显示的是HDD(机械硬盘),而实际上该笔记本的硬盘类型为SSD  81
以openkylin为例编译安装内核  76
分享解决宏碁电脑关机时自动重启的方法  73
统信uosboot区分未挂载导致更新备份失败  63
分享如何解决报错:归档 xxx.deb 对成员 control.tar.zst 使用了未知的压缩,放弃操作  63
统信uos安装mysql的实例参考  60
格之格打印机dp3300系列国产系统uos打印机驱动选择  57
在银河麒麟高级服务器操作系统V10SP3中,需要将默认shell类型修改为csh。  51
MySQL国产平替最佳选择---万里数据库(GreatDB)  45
最近下载排行榜
银河麒麟桌面操作系统V10SP1-2403-update1版本中,通过“麒麟管家-设备管理-硬件信息-硬盘”查看硬盘类型时,显示的是HDD(机械硬盘),而实际上该笔记本的硬盘类型为SSD 0
以openkylin为例编译安装内核 0
分享解决宏碁电脑关机时自动重启的方法 0
统信uosboot区分未挂载导致更新备份失败 0
分享如何解决报错:归档 xxx.deb 对成员 control.tar.zst 使用了未知的压缩,放弃操作 0
统信uos安装mysql的实例参考 0
格之格打印机dp3300系列国产系统uos打印机驱动选择 0
在银河麒麟高级服务器操作系统V10SP3中,需要将默认shell类型修改为csh。 0
MySQL国产平替最佳选择---万里数据库(GreatDB) 0
作者收入月榜
1

prtyaa 收益400.83元

2

zlj141319 收益237.91元

3

哆啦漫漫喵 收益231.52元

4

IT-feng 收益219.92元

5

1843880570 收益214.2元

6

风晓 收益208.24元

7

777 收益173.17元

8

Fhawking 收益106.6元

9

信创来了 收益106.03元

10

克里斯蒂亚诺诺 收益91.08元

请使用微信扫码

添加我为好友,拉您入交流群!

请使用微信扫一扫!