java中几个常见的问题

1.正确使用equals方法

Object的equals方法容易抛出空指针异常,应使用常量或确定有值的对象来调用equals方法

例如:

//不能使用一个值为null的引用类型变量来调用非静态方法,否则会抛出异常
String str = null;
if (str.equals("java")) {
    ...
}
else {
    ...
}

如果运行上面的程序则会抛出空指针异常,但是我们把第二行的条件判断语句改为下面这样的话,就不会抛出空指针异常,else语句可以得到执行:

String str = null;
if ("java".equals(str)) {
    ...
}
else {
    ...
}

但是更推荐用java.util包下的Objects类中的equals方法来判断:

Objects.equals(null, "java);

Objects的equals方法源码如下所示:

public static boolean equals(Object a, Object b) {
    // 可以避免空指针异常,如果a==null就不会执行到a.equals(b)
    return (a == b) || (a != null && a.equals(b));
}

2.整型包装类值的比较

所有整型包装类值的比较必须使用equals方法

例如:

Integer x = 3;
Integer y = 3;
System.out.println(x == y); // true
Integer a = new Integer(3);
Integer b = new Integer(3);
System.out.println(a == b); // false
System.out.println(a.equals(b)); // true

当使用自动装箱方式创建一个Integer对象并且数值在-127 - 128时,会将创建的Integer对象缓存起来,当下次再次出现该值时,直接从缓存中取出对应的Integer对象,所以x和y引用的是相同的Integer对象。

当如果想比较整型包装类的值时,因为a和b是不同的对象,所以用“==”比较的地址返回的是false,此时应当用equals方法进行比较。

3.BigDecimal

3.1 BigDecimal的用处

浮点数之间的等值判断,基本数据类型不能用==来比较。具体原理和浮点数的编码方式有关,这里就不再多提。

        float a = 1.0f - 0.9f;
        float b = 0.9f - 0.8f;
        System.out.println(a); // 0.100000024
        System.out.println(b); // 0.099999964
        System.out.println(a == b); // false

上述结果是由于浮点数的精度丢失引起的,那么我们应该如何解决这个问题呢?一种很常用的方法就是:使用BigDecimal类来定义浮点数的值,再进行浮点数的运算操作。

        BigDecimal a = new BigDecimal("1.0");
        BigDecimal b = new BigDecimal("0.9");
        BigDecimal c = new BigDecimal("0.8");
        BigDecimal x = a.subtract(b); // 0.1
        BigDecimal y = b.subtract(c); // 0.1
        System.out.println(x == y); // true

3.2 BigDecimal的比较

a.compareTo(b):返回-1表示小于,0表示相等,1表示大于。

BigDecimal a = new BigDecimal("0.9");
BigDecimal b = new BigDecimal("0.8");
System.out.println(a.compareTo(b)); // 1

3.3 BigDecimal保留几位小数

通过setScale()方法设置保留几位小数以及保留规则。

        BigDecimal a = new BigDecimal("1.255433");
        BigDecimal b = a.setScale(3, BigDecimal.ROUND_HALF_DOWN);
        System.out.println(b); // 1.255

3.4 BigDecimal的使用注意事项

我们在使用BigDecimal时,为了防止精度丢失,推荐使用它的BigDecimal(String)的构造方法来创建对象,或者使用BigDecimal的valueOf方法,而不能使用BigDecimal(double)的方式,因为该方法存在精度丢失的风险。

posted @ 2019-07-16 19:14  murphy_gb  阅读(1002)  评论(0编辑  收藏  举报