Java高级-包装类、BigDecimal和BigInteger

基本数据类型和包装类

        基本数据类型和包装类如下所示:

基本类型包装类
intjava.lang.Integer。父类为java.lang.Number
longjava.lang.Long。父类为java.lang.Number
doublejava.lang.Double。父类为java.lang.Number
charjava.lang.Character。父类为java.lang.Object
booleanjava.lang.Boolean。父类为java.lang.Object
bytejava.lang.Byte。父类为java.lang.Number
floatjava.lang.Float。父类为java.lang.Number
shortjava.lang.Short。父类为java.lang.Number

      8种数据类型的包装类除了Character和Boolean之外,都是继承自Number类

自动装箱与自动拆箱

     在JDK1.5及以后,增加了自动装箱与拆箱的新特性。如下所示:

public class Test1 {
    public static void main(String[] args) {
        Integer x = 1;   //自动装箱
        int y = x;       //自动拆箱
    }
}

自动装箱

      装箱就是将基本数据类型转换为包装类型。如下所示:

Integer x = 1;
会执行如下代码:
Integer x = Integer.valueOf(1);

自动拆箱

      拆箱就是将包装类型转换位基本数据类型,如下所示:

int y = x;
会执行如下代码:
int y = x.intValue();

注意事项

  • 装箱操作会创建对象,频繁的装箱操作会消耗许多内存,影响性能,所以可以避免装箱的时候应该尽量避免。
  • NullPointerException空指针异常
Integer x = null;
int b = x;   //会报NullPointerException异常
  • 当 "=="运算符的两个操作数都是包装器类型的引用,则是比较指向的是否是同一个对象;而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)。
  • 对于包装器类型,equals方法并不会进行类型转换
  • Integer i = new Integer(xxx)和Integer i =xxx;这两种方式的区别
1.第一种方式不会触发自动装箱的过程;而第二种方式会触发;
2.在执行效率和资源占用上的区别。第二种方式的执行效率和资源占用在一般性情况下要优于第一种情况(注意这并不是绝对的)。

案例分析1

       如下所示:

public class Test4 {
    public static void main(String[] args) {
        int a = 100;
        Integer b = 100;
        System.out.println(a == b);
		
        Integer c = 100;
        Integer d = 100;
        System.out.println(c == d);
		
        Integer e = 200;
        Integer f = 200;
        Integer.valueOf(20);
        System.out.println(e == f);
	}
}
结果为:
true
true 
false

      分析:

  • 第1段代码,基础类型a与包装类b进行==比较,这时b会拆箱,直接比较值,所以会打印true
  • 第2段和第3段代码,输出结果表明c和d指向的是同一个对象,而e和f指向的是不同的对象。故打印true和false。

          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);
}

        可以看到,这里的实现并不是简单的new Integer,而是用IntegerCache做一个cache,cache的range是可以配置的。IntegerCache源码如下:

 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() {}
}

         这是IntegerCache静态代码块中的一段,默认Integer cache 的下限是-128,上限默认127,可以配置,所以到这里就清楚了,在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。

        在上面当赋值100给Integer时,刚好在这个range内,所以从cache中取已经存在的Integer对象并返回,所以二次返回的是同一个对象,所以==比较是相等的;当赋值200给Integer时,不在cache 的范围内,所以会new Integer并返回,当然==比较的结果是不相等的。

       注意:Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的,故会有一样的效果。

       如Long类的valueOf源码如下:

public static Long valueOf(long l) {
    final int offset = 128;
        if (l >= -128 && l <= 127) { // will cache
            return LongCache.cache[(int)l + offset];
        }
    return new Long(l);
}

案例分析2

public class Test5 {
    public static void main(String[] args) {
        Boolean b1 = false;
        Boolean b2 = false;
        Boolean b3 = true;
        Boolean b4 = true;
		
        Double d1 = 100.0;
        Double d2 = 100.0;
        System.out.println(d1 == d2);
		
        Double d3 = 200.0;
        Double d4 = 200.0;
        System.out.println(d3 == d4);
	}
}
结果为:
false
false

       Double类的valueOf源码如下:

public final class Double extends Number implements Comparable<Double> {
    ...
    public static Double valueOf(String s) throws NumberFormatException {
        return new Double(parseDouble(s));
    }
    public static Double valueOf(double d) {
        return new Double(d);
    }
    public Double(double value) {
        this.value = value;
    }
}

        从上面可以看出,在某个范围内的整型数值的个数是有限的,而浮点数却不是

        注意:Double、Float的valueOf方法的实现是类似的, 故也会有一样的效果。  

案例分析3

public class Test {
    public static void main(String[] args) {
        Boolean b1 = false;
        Boolean b2 = false;
        System.out.println(b1 == b2);
		
        Boolean b3 = true;
        Boolean b4 = true;
        System.out.println(b3 == b4);
    }
}
结果:
true
true

        Boolean类的valueOf源码如下:

public final class Boolean implements java.io.Serializable, Comparable<Boolean>{
    public static final Boolean TRUE = new Boolean(true);
    public static final Boolean FALSE = new Boolean(false);    
    ...

    public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
    }

    public static Boolean valueOf(String s) {
        return parseBoolean(s) ? TRUE : FALSE;
    }
}

          可以看到,TRUE和FALSE是两个静态成员属性,这就是为什么输出两个true的原因了。

 

BigDecimal

         double和flaot在计算时会有精度的丢失,因此在需要精确计算时,使用BigDecimal。 如下所示:

double d1 = 2.01;
double d2 = 0.01;
double d3 = d1 - d2;
System.out.println(d3);
结果值为:1.9999999999999998

使用  

        BigDecimal位于java.math包中。使用如下所示:

BigDecimal x = new BigDecimal("2.01");
BigDecimal y = new BigDecimal("0.01");
BigDecimal z = x.subtract(y);   //做减法运算
System.out.println(z);   //打印结果值为2.00,默认调用z.toString

常用API            

add做加法运算
subtract做减法运算
multiply做乘法运算
divide做除法运算

      

BigInteger

概念       

       用于int和long取值范围有限,故有BigInteger。BigInteger位于java.math包下,可以描述一个无穷大的整数,理论上BigInteger的储存值范围只受内存的限制。

使用

 

API

 

 

参考:

https://www.jianshu.com/p/bbe6bffcb03b

https://www.cnblogs.com/dolphin0520/p/3780005.html

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luckyliuqs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值