记录一些在工作中出现的不应该或少见的错误,如 Java 基础、Spring 基础等常识问题以及生僻的知识,用于笔记,也用于警示。
一、Java
1. Long 等数字类型比较
1.1 问题描述:在进行两个 Long 对象比较时,直接用了“==”,如:a.id==b.id,经过简单测试没问题,然后就提交了,使用一段时间后,发现出现问题,一样的值结果是 false;
1.2 处理过程:第一感觉就是不该用“==”,一般情况下都是 Long 对象和 long 值比较,如a.id=1,会发生自动拆箱,是没有问题的;左右都是包装类型的时候直接双等于肯定是错的,但是困惑的是,测试的时候为什么是对的,经过网上一番查询,才知道 127 是个分界岭;
1.3 问题说明:Long 中有一个静态的内部类 LongCache,缓存了 -128 至 127 之间的值,如果传入的值在此范围内,则直接从缓存中返回引用,否则新建 Long 实例;因此,超过 127,双等于就错了;
1.4 正确方法,推荐优先级由上至下:
equals()方法,如:
a.equals(b),看源码可知,经过重写,会比较对象的值;longValue()方法,如:
a.longValue()==b.longValue(),先拆箱,再比较;compareTo()方法,如:
a.compareTo(b)==0,比较大小,返回差值;1.5 扩展:Byte、Short、Integer、Long 等整形数字都是一样的情况;Float、Double 两个浮点类型,没有内部静态缓存,比较方法一样。
二、SpringBoot
1. 配置文件读取
1.1 问题描述:
一般情况下,会在配置文件里
application.yml定义自定义配置项,如下:1
2
3
4# 项目配置
custom:
# 名称
name: test读取配置属性,定义对应的配置 JavaBean,如下:
1
2
3
4
5
6
7
8
9
10
public class CustomConfig {
/**
* 名称
*/
private static String name;
// get、set 方法省略
}情形说明:
- 这一套代码在项目里已经正常使用,这天,要加个新属性;
- 很简单的操作,先在配置文件里加配置属性,再在类里加属性和 set/get 方法;然后提交了,告别人加完了;这么简单,还用测试吗?
- 打脸来的很快,同事说获取到的属性是 null;尴尬,自己写个单元测试,确实取不到值;
1.2 问题解决:
看来看去、改来改去都没效果,set/get 方法也没缺少,也没发现框架里有什么特殊处理;
经过仔细比对,发现 set 方法是 static 的,是唯一和其他属性不一致的地方,好吧,修改后再测试,取到了;
问题就出在 set 方法是静态的,因为属性是静态的,IDEA 生成 set/get 方法自然也是静态的,没意识到有什么问题;
正确写法:
1
2
3
4
5
6
7
8
9private static String name;
public static String getName() {
return name;
}
// 重点注意去掉 static 修饰符
public void setName(String name) {
RuoYiConfig.name = name;
}
1.3 问题解释:
- 经网友提醒,根据 Springboot 源码,@ConfigurationProperties 只会调用非静态的 set 方法;
- @ConfigurationProperties 会根据配置文件的属性调用对应的 set 方法;
- 切记:prefix 值必须全部为小写,set 方法必须为 public 且非 static;
三、Thymeleaf
1. th:if 标签
1.1 问题描述:
- 原使用场景是,当属性不为空时,div 存在,反之,div 不存在。
- 但是,按照语法写来写去,结果都不对。要不然就是一直出现,要不然就是一直不出现。
- 刚开始以为是语法不对,试了几种,都是一样的结果。
- 后灵光一现,猜测错误原因并验证,最终解决。
1.2 正确写法:
1 | <form class="form-horizontal m" id="form-equipment-edit" th:object="${equipment}"> |
1.3 说明:
- 关键在于
th:if="${not #strings.isEmpty(equipment.userManualShowName)}"里的equipment.userManualShowName。 - 原错误写法:
userManualShowName。因为在 form 中已经绑定了对象th:object="${equipment}",所以里面的 input 中可以直接访问属性th:field="*{userManualShowName}"。自然在写 if 标签时也用了同样写法。 - 但是,form 绑定的对象和 div 是没关系的,所以 div 访问还是需要通过对象访问属性,即
equipment.userManualShowName。
2. th:data 事件传参
1.1 情景描述:
在详情页面中出现点击操作,可能需要将后台的值绑定并当作参数传入点击事件。
1.2 正确写法:
1 | <a th:data-umr="${equipment.userManualRealName}" onclick="downloadFile(this.getAttribute('data-umr'))">[[${equipment.userManualShowName}]]</a> |
1.3 说明:
通过 th:data- 自定义属性接收参数值,再通过 this.getAttribute('data-umr') 获取。
原文链接: https://xinghuipeng.pages.dev/2022/10/12/work/misc/工作错题录/
版权声明: 转载请注明出处.