必坑指南Java日常开发中的20个坑,你踩过几个?

1. 六类典型空指针问题

  • 包装类型的空指针问题

  • 级联调用的空指针问题

  • Equals方法左边的空指针问题

  • ConcurrentHashMap 这样的容器不支持 Key 和 Value 为 null。

  • 集合,数组直接获取元素

  • 对象直接获取属性

1.1包装类型的空指针问题

public class NullPointTest {

    public static void main(String[] args) throws InterruptedException {
        System.out.println(testInteger(null));
    }

    private static Integer testInteger(Integer i) {
        return i + 1;  //包装类型,传参可能为null,直接计算,则会导致空指针问题
    }
}

1.2 级联调用的空指针问题

public class NullPointTest {
    public static void main(String[] args) {
       //fruitService.getAppleService() 可能为空,会导致空指针问题
        fruitService.getAppleService().getWeight().equals("OK");
    }
}

1.3 Equals方法左边的空指针问题

public class NullPointTest {
    public static void main(String[] args) {
        String s = null;
        if (s.equals("公众号:Java技术栈,666")) { //s可能为空,会导致空指针问题
            System.out.println("666");
        }
    }
}

1.4 ConcurrentHashMap 这样的容器不支持 Key,Value 为 null。

public class NullPointTest {
    public static void main(String[] args) {
        Map map = new ConcurrentHashMap<>();
        String key = null;
        String value = null;
        map.put(key, value);
    }
}

1.5  集合,数组直接获取元素

public class NullPointTest {
    public static void main(String[] args) {
        int [] array=null;
        List list = null;
        System.out.println(array[0]); //空指针异常
        System.out.println(list.get(0)); //空指针一场
    }
}

1.6 对象直接获取属性

public class NullPointTest {
    public static void main(String[] args) {
        User user=null;
        System.out.println(user.getAge()); //空指针异常
    }
}

2. 日期YYYY格式设置的坑

日常开发,经常需要对日期格式化,但是呢,年份设置为YYYY大写的时候,是有坑的哦。YYYY-MM-DD 的黑锅,我们不背!这篇推荐看下。

反例:

Calendar calendar = Calendar.getInstance();
calendar.set(2019, Calendar.DECEMBER, 31);

Date testDate = calendar.getTime();

SimpleDateFormat dtf = new SimpleDateFormat("YYYY-MM-dd");
System.out.println("2019-12-31 转 YYYY-MM-dd 格式后 " + dtf.format(testDate));

运行结果:

2019-12-31 转 YYYY-MM-dd 格式后 2020-12-31

「解析:」

为什么明明是2019年12月31号,就转了一下格式,就变成了2020年12月31号了?因为YYYY是基于周来计算年的,它指向当天所在周属于的年份,一周从周日开始算起,周六结束,只要本周跨年,那么这一周就算下一年的了。正确姿势是使用yyyy格式。

正例:

Calendar calendar = Calendar.getInstance();
calendar.set(2019, Calendar.DECEMBER, 31);

Date testDate = calendar.getTime();

SimpleDateFormat dtf = new SimpleDateFormat("yyyy-MM-dd");
System.out.println("2019-12-31 转 yyyy-MM-dd 格式后 " + dtf.format(testDate));

3.金额数值计算精度的坑

看下这个浮点数计算的例子吧:

public class DoubleTest {
    public static void main(String[] args) {
        System.out.println(0.1+0.2);
        System.out.println(1.0-0.8);
        System.out.println(4.015*100);
        System.out.println(123.3/100);

        double amount1 = 3.15;
        double amount2 = 2.10;
        if (amount1 - amount2 == 1.05){
            System.out.println("OK");
        }
    }
}

运行结果:

0.30000000000000004
0.19999999999999996
401.49999999999994
1.2329999999999999

可以发现,结算结果跟我们预期不一致,其实是因为计算机是以二进制存储数值的,对于浮点数也是。对于计算机而言,0.1无法精确表达,这就是为什么浮点数会导致精确度缺失的。因此,「金额计算,一般都是用BigDecimal 类型」

Java中的运算神器 BigDecimal,了解一下?

对于以上例子,我们改为BigDecimal,再看看运行效果:

System.out.println(new BigDecimal(0.1).add(new BigDecimal(0.2)));
System.out.println(new BigDecimal(1.0).subtract(new BigDecimal(0.8)));
System.out.println(new BigDecimal(4.015).multiply(new BigDecimal(100)));
System.out.println(new BigDecimal(123.3).divide(new BigDecimal(100)));

运行结果:

0.3000000000000000166533453693773481063544750213623046875
0.1999999999999999555910790149937383830547332763671875
401.49999999999996802557689079549163579940795898437500
1.232999999999999971578290569595992565155029296875

发现结果还是不对,「其实」,使用 BigDecimal 表示和计算浮点数,必须使用「字符串的构造方法」来初始化 BigDecimal,正例如下:

public clas
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值