2020年这11个Java开发的坑,可把我害惨了!

286 阅读3分钟

前言

常常我们在使用过程中遇到一些不注意的坑,今天就简单罗列一些常见的问题

拆箱出现NPE

如下图,方法中使用基本类型,调用的时候没有判断null,直接传入包装类型,极容易导致拆箱出现NPE

Java一些不注意的坑

建议:方法入参使用包装类型

诡异的整型cache导致的现象

由于Java中整型如Integer、Short、Long类型存在cache,默认-127~128之间值是返回同一个对象,因此相等,可以通过再jvm启动指定参数-XX:AutoBoxCacheMax=128,修改cache最大值的大小。

Java一些不注意的坑

建议:数据的比较,如果是包装类型使用equals比较,或者全部转成基本类型使用==

Arrays.asList使用不当,容易出现异常

由于Arrays.asList返回的list属于AbstractList,没有add、remove相关方法,一旦使用则会抛出异常

Java一些不注意的坑

建议:可以通过将Arrays.asList的结果传入到ArrayList构造器中,如下

List ints = new ArrayList<>(Arrays.asList(1, 2, 3));

对返回List等集合的方法返回的参数进行操作

由于在日常开发中,很多团队对返回集合的方法,要求没有数据,也需要返回一个空的集合,如下

Java一些不注意的坑

一旦返回空集合,对于使用方,直接使用,可能会出现UnsupportedOperationException。

建议:使用方,不建议对返回的数据直接进行add、remove等操作,应该通过自定义的集合进行操作,如下

List list = getList();

List arrayList = new ArrayList<>();

arrayList.addAll(list);

arrayList.add("1");

List.toArray一不小心就报错

通常对list集合转数组,采用toArray方法,但由于泛型擦除,实际存储为Object数组,因此无法强转,如下

Java一些不注意的坑

建议:使用toArray指定返回类型,如下

List list = new ArrayList<>(Arrays.asList("a","b","c"));

String[] strings = list.toArray(new String[0]);

集合在for循环中remove

有经验的研发,基本都知道这个问题,在for循环中remove元素,会导致集合的快速失败,抛出异常

Java一些不注意的坑

建议:使用Iterator来进行remove操作

方法重载,导致方法冲突

如下,由于正常类型匹配,方法重载会正常运行,一旦传入null,即jvm无法知道实际调用的是哪个方法。

Java一些不注意的坑

实际上,编译期是无法通过的,需要指定null为哪个类型即可。

使用split方法容易出现忽略最后同名

split方法需要注意2点,一个是参数是可以填写正则表达式的,因此对于一些特殊符号需要转义;另外一个就是当最后出现连续的分隔符时,会忽略中间的内容,如下

Java一些不注意的坑

使用BigDecimal一不注意,也会出现精度问题

BigDecimal在使用的过程中,不要使用double这样的构造器去构建对象,如下图

Java一些不注意的坑

建议:一律使用BigDecimal的String构造器

使用Executors创建线程,当线程处理过慢,容易OOM

对于Executors创建的线程池,一般要么是最大线程数为Integer.MAX_VALUE,要么是采用无界队列,在高并发的场景下,极易出现OOM

Java一些不注意的坑

建议:自行通过ThreadPoolExecutor,指定参数,创建线程池

弱引用等类型如果使用不当,gc过后,仍不会销毁

Java当中存在强引用、软引用、弱引用、虚引用,其中软引用是当jvm内存不足时,释放软引用;弱引用是当执行gc的时候,会回收。

例如弱引用如果使用不当,当发生gc的时候,是不会回收的,软引用也是如此,若使用不当,即使OOM了,也不会被回收。

Java一些不注意的坑

上面的原因是str是一个强引用,因此执行gc的时候,是不会回收弱应用的。

正确的使用方法如下

Java一些不注意的坑

如果还有其他的场景的坑,欢迎大家留言,谢谢大家!