1、基本类型与包装类型、引用类型

java int与bigdecimal转换_面试


2、byte和int相互转换

// int转byte

byte b = (byte)aInt; // 取int最后一个字节,如果int值大于255,则转换不准确

// 通过inputStream.read()获取的值可以通过此方法转换

// byte转int

int I = (int)aByte; //如果要求值不变,想要进行数值计算,可采用此方式转换

3、高精度数据转换

// float和double只能用于科学计算,Double.valueOf(String) and Float.valueOf(String)都会丢失精度

// 在商业计算中应该使用java.math.BigDecimal

// 注意:BidDecimal使用String进行初始化

String d2 = “0.2”; // 注意,使用String初始化BigDecimal

BigDecimal bd1 = new BigDecimal(d2);

BigDecimal bdDivideTest2 = bd3.divide(bd4,2,BigDecimal.ROUND_CEILING);// 可能产生无限循环小数,需要截取小数

// 高精度计算
        String d1 = "0.1";
        String d2 = "0.2"; // 注意,使用String初始化BigDecimal
        BigDecimal bd1 = new BigDecimal(d1);
        BigDecimal bd2 = new BigDecimal(d2);
        BigDecimal bdAdd = bd1.add(bd2);
        System.out.println(bdAdd.toString());
        BigDecimal bdSub = bd2.subtract(bd1);
        System.out.println(bdSub.toString());
        BigDecimal bdMulti = bd2.multiply(bd1);
        System.out.println(bdMulti.toString());
        BigDecimal bdDivide = bd2.divide(bd1); // 可能产生无限循环小数,抛出异常:java.lang.ArithmeticException: Non-terminating decimal expansion
        // 例如
        String d3 = "0.12";
        String d4 = "0.56";
        BigDecimal bd3 = new BigDecimal(d3);
        BigDecimal bd4 = new BigDecimal(d4);
//      BigDecimal bdDivideTest1 = bd3.divide(bd4); // 产生了无限循环小数
        BigDecimal bdDivideTest2 = bd3.divide(bd4,2,BigDecimal.ROUND_CEILING); // 解决方法,主动截取小数位数

        // 如何保留两位小数 
        double d5 = 11.32542;
        BigDecimal bd5 = new BigDecimal(Double.toString(d5));
        double d6 = bd5.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();         //保留2位小数
        System.out.println("保留2位小数:" + d6);

4、拆箱与装箱
(1) 当封装类与基础类型进行==运算,封装类会自动拆箱,并将拆箱结果与基础类型比较;而两个封装类进行==运行时,与其它的对象进行==运行一样,对比两个对象的地址
(2) 如果一个方法中参数类型为原始数据类型,所传入的参数类型为其封装类,则会自动对其进行拆箱;相应,如果一个方法中参数类型为封装类型,所传入的参数类型为其原始数据类型,则会自动对其进行装箱

Integer i = 100;  // 自动装箱
        Integer j = new Integer(100); // 强制在堆中新建对象
        int w = 100;
        System.out.println(w == i);  // 结果为true,说明:==用于比较引用,从结果来看是自动拆箱(Integer.intValue)后进行比较,如果是自动装箱后比较则结果应该为false
        System.out.println(w == j);  // 结果为true,说明:同理
        System.out.println(i == j);  // 结果为false
        System.out.println(i.equals(w)); // 结果为true,说明:equals接收Object作为参数,说明w被自动装箱了,但是equals内部使用了Integer.intValue进行数值比较,所以返回true

(3) Integer缓存

Integer t1 = 100;
        Integer t2 = 100;
        Integer t3 = 254;
        Integer t4 = 254;
        Integer t5 = 300;
        Integer t6 = 300;
        System.out.println(t1 == t2); // 结果为true,t1和t2指向了同一个对象,说明使用了Integer缓存(-128-127),用于提高性能
        System.out.println(t3 == t4); // 结果为false
        System.out.println(t5 == t6); // 结果为false

需要注意的问题:
(1)int与Integer比较
Integer t7 = null;
int i = 100;
System.out.println(t7 ==i); // 会抛出NullPointerException,原因是自动拆箱使用了Integer.intValue()
(2)Integer作为类变量
Integer作为类变量时(Integer num1;),属于引用类型变量,默认初始化为null
因此如果调用person.getNum1() + 1;同样会触发自动拆箱导致空指针异常

解决办法是在类构造函数中,给num1初始化