day01

一、金融相关金额计算BigDecimal(浮点型经度计算)

  浮点型精度损失问题用BigDecimal类型,参数传递字符串类型(把字符串拆成字节数组进行计算);

  加(add)减(subtract)乘(multipy)除(divide)绝对值(abs)

package besttest.day01;

import org.testng.annotations.Test;

import java.math.BigDecimal;

public class BigDecimalTest {

    //加运算,输入都为String类型数值
    public BigDecimal add(Object s1,Object s2){
        BigDecimal sum=null;
        try {
            BigDecimal num1 = new BigDecimal(String.valueOf(s1));
            BigDecimal num2 = new BigDecimal(String.valueOf(s2));
            sum = num1.add(num2);

        }catch (Exception e){
            e.printStackTrace();
            System.out.println("输入字符串有误");
        }
        return sum;
    }
    //减运算
    public BigDecimal delete(Object a,Object b){
        BigDecimal sum = null;
        try {
            BigDecimal num1 = new BigDecimal(String.valueOf(a));
            BigDecimal num2 = new BigDecimal(String.valueOf(b));
            sum = num1.subtract(num2);
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("输入数值有误");
        }
        return sum;
    }
    //乘法运算multipy()
    public BigDecimal multipy(Object a,Object b){
        BigDecimal sum = null;
        try {
            BigDecimal num1 = new BigDecimal(String.valueOf(a));
            BigDecimal num2 = new BigDecimal(String.valueOf(b));
            sum = num1.multiply(num2);
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("输入数值有误");
        }
        return sum;
    }
    //除法运算divide()
    public BigDecimal divide(Object a,Object b){
        BigDecimal sum = null;
        try {
            BigDecimal num1 = new BigDecimal(String.valueOf(a));
            BigDecimal num2 = new BigDecimal(String.valueOf(b));
            sum = num1.divide(num2);
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("输入数值有误");
        }
        return sum;
    }


    public static void main(String[] args) {
        BigDecimalTest bigDecimal = new BigDecimalTest();
        BigDecimal result1 = bigDecimal.add(new BigDecimal("400000000000.0909"),new BigDecimal("909909988899.00"));
        System.out.println(result1);
        result1 = bigDecimal.add(4000.099898,1009494.389283444);
        System.out.println(result1);
        result1 =  bigDecimal.add("333334444.33333","0990993039.999999999");
        System.out.println(result1);
    }
    //减法测试
    @Test
    public void deleteTest(){
        BigDecimalTest bigDecimalTest = new BigDecimalTest();
        BigDecimal result1 = bigDecimalTest.delete(999999999.0000,090900.09090099);
        BigDecimal result2 = bigDecimalTest.delete("99989.99888777","76766666.99");
        BigDecimal result3 = bigDecimalTest.delete("989988.878",900000.00);
        System.out.println("result1:"+result1+"  result2:"+result2+"  result3"+result3);
    }
    //乘法测试
    @Test
    public void multipyTest(){
        BigDecimalTest bigDecimalTest = new BigDecimalTest();
        BigDecimal result1 = bigDecimalTest.multipy(999999999.0000,090900.09090099);
        BigDecimal result2 = bigDecimalTest.multipy("99989.99888777","76766666.99");
        BigDecimal result3 = bigDecimalTest.multipy("989988.878",900000.00);
        BigDecimal result4 = bigDecimalTest.multipy("99988889",990900.90);
        BigDecimal result5 = bigDecimalTest.multipy("adb","888");
        System.out.println("result1:"+result1+"  result2:"+result2+"  result3:"+result3
        +"  result4:"+result4+"   result5:"+result5);
        System.out.println(new BigDecimal("123").abs());
    }
}
BigDicimal

二、int和Integer的区别是什么?

  1、类型差别

    int是java的8个原始类型(int、short、char、float、double、Boolean、long、byte)之一,这几个原始类型不是对象;

    Integer是对int的一个包装,是对象,符合java中万事万物皆对象的思想,包装了很多常用的操作。

  2、存储的微众,大小

    int是由jvm底层提供,有java虚拟机规范,int类型数据存储在局部变量去,占用一个数组单元;

    Integer存储在java运行时数据区的堆中,不在使用时刻被垃圾回收机制回收。

      Integer对象大小:

        Mark Word:4个字节,标记位

        Class对象指针:4字节,指向对应class对象的内存地址

        对齐:对齐填充字节,按照8个字节填充

        4+4+8=16字节

  3、使用时,字节码的区别:

    int类型字节码实例:

      定义:int num1 = 32;

      字节码:0:bipush 32

    Integer类型字节码实例:

      定义:Integer num2 = 64

      字节码:

        3:bipush 64

        5:invokestatic #20 //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;

    联系:

      相互转化:

        Integer.valueOf(int)-->int 类型转为Integer类型

        Integer.intValue()  -->Integer类型转为int类型

        当然也可以直接相互赋值:int num1 = 11;Integer num 2= num1;也是可以的

      自动拆装箱操作(auto boxing/unboxing)

        int --> Integer,装箱

        Integer -->int,拆箱

        注意:程序中尽量避免无意义的拆装箱操作,尤其是有性能考虑时(对象的创建回收)

    Integer缓存机制源码分析:(Integer.valueOf())     

public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

//int转为Integer类型时,首先判断int值是否在缓存当中,如果在,就不会再去创建Integer对象;
//缓存的数值范围(该段源码设置低位-128,高位127;):
private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }
Integer.valueOf()

      ==说明:若为原始类型则比较值是否相等,若为对象,则比对地址是否相同;如下例子,Integer对象,值都相等,但是当值为128时,地址不相同,值为127值却相同

          说明Integer缓存机制生效

@Test
    public void test2(){
        Integer i1 = 128;
        Integer i2 = 128;
        System.out.println(i2 == i1);//结果:false

        Integer i3 = 127;
        Integer i4 = 127;
        System.out.println(i3 == i4);//结果:true
    }

      -XX:AutoBoxCacheMax=256:通过将此JVM配置项添加到jvm中,可以调整如上代码总high的高位为256;

        idea中选择工具栏中运行左边的下拉框,点击Edit Configurations,配置VM options 为:-ea -XX:AutoBoxCacheMax=256,保存

        服务器上启动参数配置jvm参数

    注意事项:在做相等判断时,若为元素类型则可以直接使用==,若为包装类型则需要使用equals

         业务中若使用包装类型,要注意默认值是null的,这里最容易疏忽,因为元素类型默认值是0给大家养成了没有做null的不好习惯

    扩展:

      其它基本数据类型与对应的包装类型是否类型?是的

      既然你看过源码,那么自动拆装箱时是否会使用到缓存机制呢?有,在生成字节码时,系统会自动调用Integer.valueOf()方法,用到这个方法,自然用到缓存机制

      既然你看过源码,自动拆装箱时为啥可以做到自动转化?

        语法糖

        编译支持(字节码)

      既然看过源码,也提到了Integer的缓存最大是127,但是我的系统中会有很多整数的使用,一般范围怎么调大

        -XX:AutoBoxCacheMax=256

      既然看过源码,说一下有哪些设计要点?

        不可变性:

          猜测:Integer内部装载的依旧是整数,而在相互转化时,可以基于intValue()获取int值,那就从

          return value;

          private final int value;

          进而可知,Integer对象定义的对象也是不可变的

          好处?保证了基本的信息安全和并发编程中的线程安全

        移植性:

          在64位操作系统写的代码移植到32位系统上,数据会否发生变化?

          在Integer中定义了常量:

            @Native public static final int SIZE = 32;

            public static final int BYTES = SIZE/Byte.SIZE

          java语言规范:无论是32位还是64位,开发者不需要担心位数的问题

      有了Integer还要int干啥?或者有了int还要Integer干啥?

      java号称纯面向对象,为啥搞一批原始类型让人去诟病,面向对象的一点不纯粹呢?

        工程上的考虑,基本数据类型在执行效率和内存使用上提升软件性能,想想java刚出生的年代,硬件系统内存系统都没有现在那般牛逼,所以性能是工程师及其重视的问题。

        其它?泛型的设计和考虑

      查看生成的字节码:javap -vervose 类名   (注意,类名后面没有后缀)

      

原文地址:https://www.cnblogs.com/wangkc/p/10933602.html