java 开发注意点
Spring
springaop
cannot find subclass final class AutoConfigurationPackage··
原因是因为切面定义的太大了,没办法实现 AOP,需要缩小范围
@PointCut("execution(public * *(..))")
@Transactional
不生效的问题
- 问题
- 方法没有定义为 public 类型
- 在类内部中去调用标有@Transactional 的方法(必须通过接口去调用,因为是通过 AOP 切面来实现的,如果是类内部自己调自己,相当于用 this 方法调用的)
- exception 被吃掉了,没有正确抛出
tomcat 线程复用
为了提高性能,复用线程,当使用 ThreadLocal 存储线程私有变量时,要注意在执行完程序后的 finally 块中进行关闭
ThreadLocal.remove();
BUG:TestEngine with ID ‘junit-vintage’ failed to discover tests
将冲突的 junit version 删除,比如我这里只保留了
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.5.2</version>
<scope>test</scope>
</dependency>
BUG
apache CollectionUtils.removeAll 的 bug
背景:3.2.1 版本,建议升级版本内容
Collection removeAll(Collection source,Collection remove){
// 里面调用的是retainAll,调错了函数
ListUtils.retainAll(source,remove);
}
Path already set
@RestController(value="xx")
这个的 value 是 bean 名字,不是@RequestMapping("/dwd/dw")
的路径
io
- 读取文件
当使用 BufferedReader.readLine()读取行时,应注意文件行内存溢出的问题,可以通过 org.apache.commons.io.input.BoundedInPutStream 对流进行大小限制,再进行 readLine()读取
BoundedInputStream bis=new BoundedInputStream(new FileInputStream(new File('xxxx')),10*1024*1024);
InputStreamReader reader=new InputStreamReader(bis,"UTF-8")
***
比较
- 字符串比较
当使用 String.compareTo,对 string 排序时,应注意此处是按位比较,比如“1234” 和 “223”比较,“223”是比“1234”大的,因为它是首字母排序。
// 底层比较函数
public static int compareTo(byte[] value, byte[] other, int len1, int len2) {
int lim = Math.min(len1, len2);
for(int k = 0; k < lim; ++k) {
if (value[k] != other[k]) {
return getChar(value, k) - getChar(other, k);
}
}
return len1 - len2;
}
// 测试代码
public static void main(String[] args) {
String a = "223";
String b = "1234";
String c = "2234";
System.out.println(a.compareTo(b));
System.out.println(c.compareTo(b));
}
// 输出
// 1
// 1
时间
- SimpleDateFormat
- 非线程安全,为解决这个问题,上锁或者创建新对象开销大
- 对于时区以及 api 不优化,此处主要是兼容旧版 api 的缘故
// 类变量
// public abstract class DateFormat extends Format {
// protected Calendar calendar;
private StringBuffer format(Date date, StringBuffer toAppendTo, FieldDelegate delegate) {
// 私有变量设置时间,当对static修饰对象时产生多时间值
this.calendar.setTime(date);
boolean useDateFormatSymbols = this.useDateFormatSymbols();
int i = 0;
while(i < this.compiledPattern.length) {
int tag = this.compiledPattern[i] >>> 8;
int count = this.compiledPattern[i++] & 255;
if (count == 255) {
count = this.compiledPattern[i++] << 16;
count |= this.compiledPattern[i++];
}
switch(tag) {
case 100:
toAppendTo.append((char)count);
break;
case 101:
toAppendTo.append(this.compiledPattern, i, count);
i += count;
break;
default:
this.subFormat(tag, count, delegate, toAppendTo, useDateFormatSymbols);
}
}
return toAppendTo;
}
JDK8 下可替换为新的类进行处理:LocalDateTime
,Instant
-> 时间戳,Duration
时间段,Clock
时钟类,ZoneId
时区,ZoneOffset
时区补偿